Запрос двух таблиц и объединение результатов на основе created_at

#laravel #laravel-5 #eloquent #laravel-5.3

#laravel #laravel-5 #красноречивый #laravel-5.3

Вопрос:

У меня есть две таблицы, cities и towns .

Что мне нужно сделать, это запросить эти две таблицы, объединить их результаты и упорядочить их по created_at столбцам. Кроме того, мне нужно ограничить его в общей сложности 25 результатами. Мне также нужно как-то различать, какая запись принадлежит cities , а какая принадлежит towns при отображении их в моем представлении.

Это то, что у меня есть на данный момент, но я не думаю, что это правильный способ сделать это:

 $cities = City::orderBy('created_at', 'DESC')
    ->get();

$towns = Town::orderBy('created_at', 'DESC')
    ->get();

$results = array_merge($cities->toArray(), $towns->toArray());
usort($results, function($a, $b)
{
    return $a['created_at'] < $b['created_at'];
});

return $results;
  

Проблема с этим заключается в том, что он не ограничивает его в общей сложности 25 результатами. Я также не уверен, что это лучший способ сделать это.

Вторая проблема, которую мне нужно решить, — это отображение результатов в моем представлении. Мне нужен способ отличить, какая запись принадлежит какой таблице.

На мой взгляд, у меня есть что-то вроде:

 @foreach ($results as $result)
    @if (CHECK IF RESULT IS CITY)

    @else (CHECK IF RESULT IS TOWN)

    @endif
@endforeach
  

Как я могу проверить, какая запись принадлежит какой таблице?

Комментарии:

1. Есть ли какая-либо связь между городом и городом?

2. Единственная связь заключается в том, что в towns таблице есть city_id столбец, если город находится рядом или в пределах более крупного города.

Ответ №1:

объедините 2 результата сбора, затем упорядочите их по дате по убыванию, затем возьмите 25

 $cities = City::orderBy('created_at', 'DESC')
    ->get();

$towns = Town::orderBy('created_at', 'DESC')
    ->get();
$merged = $cities->merge($towns);
  

затем отсортируйте их

$sorted = $collection->sortByDesc('created_at');

наконец, возьмите 25

 $results = $sorted->take(25);
  

если вы хотите знать, какой моделью является объект, вы можете использовать встроенную is_a функцию

 @foreach ($results as $result)
    @if (is_a($result, AppCity::class))

    @else (is_a($result, AppTown::class))

    @endif
@endforeach
  

Ответ №2:

Я не уверен, сработает ли это или нет, потому что я не тестировал его, но я чувствую, что это должно

 $cities = City::orderBy('id', 'desc')->limit(25)->get();

$towns = Town::orderBy('id', 'desc')->limit(25)->get();

$citiesAndTowns = $cities->merge($towns)->sortByDesc('created_at')->take(25);

// or use sortBy('created_at') for ascending....
  

Теперь в представлении вы можете просто сделать это таким образом…

 @foreach($citiesAndTowns as $cityOrTown)
  @if(get_class($cityOrTown) == 'AppCity')

  @else

  @endif
@endforeach
  

Или, чтобы пропустить этот грязный способ выполнения действий, вы можете сделать $citiesAndTowns->toArray() и внести изменения в представление следующим образом…

 @foreach($citiesAndTowns as $cityOrTown)
  // Since `city_id` will never be a part of city table and even if
  // it is null in Town, it will still be set....
  @if(isset($cityOrTown['city_id'])) 

  @else

  @endif
@endforeach