В моем приложении есть стена с сообщениями.
Каждое сообщение может иметь вложения, такие как Video
или Product
(и многие другие типы, поэтому создание отдельных отношений для каждого типа будет плохимидея).
Вот пример структуры базы данных:
videos
id
...
products
id
...
product_photos
product_id
...
posts
id
...
post_attachments
post_id
attachment_id
attachment_type
В Post
модели я определил отношение к PostAttachment
:
class Post extends Model
{
public function attachments()
{
$this->hasMany(PostAttachment::class);
}
}
В PostAttachment
Модель I определила полиморфное отношение к вложению:
class PostAttachment extends Model
{
public function attachment()
{
return $this->morphTo();
}
}
Если я хочу получить всю стену, я могу сделать что-то вроде этого:
$posts = Post::with([
'attachments',
'attachments.attachment'
])->get();
, что приведет к:
[
{
"id": 1,
...
"attachments": [
{
...
"attachment_type": "App\Models\Video",
"attachment": {
"id": 101,
...
}
},
{
...
"attachment_type": "App\Models\Product",
"attachment": {
"id": 203,
...
}
},
]
}
]
Но что, если я хочу добавить Product
фотографий в результат? Я не могу сделать что-то подобное:
$posts = Post::with([
'attachments',
'attachments.attachment',
'attachments.attachment.photos'
])->get();
, потому что отношение photos
существует только в модели Product
, а не в Video
.
Грязное решение - включить отношениезагрузка в определении модели:
class Product
{
protected $with = [
'photos'
];
...
}
Но с этим решением фотографии будут возвращены, даже если я получу Product
модель напрямую.
Как я могу загрузить Product
фотографии только при показеwall?
Большое спасибо заранее, и извините за мой плохой английский.