Я не могу понять, как структурировать эффективный запрос Eloquent для следующего сценария.
Пользователи могут оставаться во многих местах, таких как комнаты, квартиры, дома, поэтому у нас есть полиморфная stayable_locations таблица, но мы фокусируемся только на комнате stayable_type этой таблицы. Когда персонал нажимает на номер, мы хотим отобразить все доступные предложения номеров (если таковые доступны в таблице room_deals), а также последних 3 гостей для каждого предложения номеров (если есть).
Попытка получить этот вывод из следующих таблиц с помощью красноречия:
Room 111 (desired output for room deals and guests below)
- Room Deal #1 -> Able, Kane, Eve
- Room Deal #2 -> Eve, Adam
------------------------------------------
$room = Room::where('id',111)->first(); // room 111
// Eloquent query, not sure how to setup model relations correctly
// To get last 3 guest names per room deal [if any] in an efficient query
$room->roomDeals()->withSpecificRoomDealLast3RoomGuestNamesIfAny()->get();
Вот структура таблицы:
stayable_locations table [polymorphic]:
id | stayable_id | stayable_type | room_deal_id | room_guest_id
----------------------------------------------------------------
1 | 111 | room | 0 | 3 (Steve no room deal)
2 | 111 | room | 1 | 1 (Adam room deal)
3 | 111 | room | 1 | 2 (Eve room deal)
4 | 111 | room | 1 | 4 (Kane room deal)
5 | 111 | room | 1 | 5 (Able room deal)
6 | 111 | room | 2 | 1 (Adam room deal)
7 | 111 | room | 2 | 2 (Eve room deal)
room_deals table:
id | room_id | room_deal
-----------------------
1 | 111 | Deal A
2 | 111 | Deal B
users table:
id | name
------------
1 | Adam
2 | Eve
3 | Steve
4 | Kane
5 | Able
ОБНОВЛЕНИЕ: показаны соответствующие модели
Модель пользователя:
class User extends Authenticatable {
public function stayableLocations() {
return $this->morphMany('App\StayableLocation', 'stayable');
}
}
Модель RoomDeal:
class RoomDeal extends Model {
public function room() {
return $this->belongsTo('App\Room');
}
public function guests() {
return $this->belongsToMany('App\User', 'stayable_locations', 'room_deal_id', 'room_guest_id');
}
}
Модель StayableLocation:
class StayableLocation extends Model {
public function stayable() {
return $this->morphTo();
}
public function room() {
return $this->belongsTo('App\Room', 'stayable_id');
}
}
Модель комнаты:
class Room extends Model {
public function stayableLocations() {
return $this->morphMany('App\StayableLocation', 'stayable');
}
public function roomDeals() {
return $this->hasMany('App\RoomDeal');
}
}
Любая идея, как получить желаемый результат с помощью эффективного красноречивого запроса?
@jonasstaudenmeir Я заметил здесь ваш пакет (github.com/staudenmeir/красноречиво-нетерпеливый-лимит), но после его установки я не уверен, как правильно применить отношения модели, чтобы получить желаемый результат в виде красноречивых нетерпеливых ограниченных результатов (поскольку здесь используется полиморфное отношение, это делает его немного сложнее). Есть идеи?
Вы пробовали удаленный ответ newUserName02 (у вас он все еще где-то есть?) в сочетании с пакетом? Как определяется «последний»?
Спасибо вам, ребята! Разобрался с решением ниже. Спасибо за руководство newUserName02 и пакет @JonasStaudenmeir!






Я понял это из вспомогательных комментариев в моем вопросе. Вот так:
...], просто добавлено use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;:class User extends Authenticatable {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
...
}
class RoomDeal extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
...
}
$room = Room::find(111);
$deals3Guests = $room->roomDeals() // query deals
->with(['guests' => function($query) { // eager load guests
$query->orderBy('stayable_locations.id', 'desc') // get latest guests
->limit(3); // limit to 3
}])
->get();
Я удалил свой ответ, оказывается, Eloquent не поддерживает этот тип запроса. Если вы проверите проблемы, решаемые этим запросом на вытягивание, вы можете попробовать и другие решения: github.com/laravel/docs/pull/4918. Удачи!