Я пытаюсь установить полиморфные отношения в Laravel 4, чтобы у меня был один класс Image, который обрабатывает все, что связано с загрузкой, отключает и т. Д., А затем использовать его несколькими разными моделями. Все в порядке, пока я не попытаюсь создать несколько ссылок из одной и той же модели.
Например, у меня в настоящее время есть что-то вроде этого:
Модели / image.php
class Image extends Eloquent { public function of() { return $this->morphTo(); } }
Модели / Person.php
class Person extends Eloquent { public function mugshot() { return $this->morphOne('Image', 'of'); } public function photos() { return $this->morphMany('Image', 'of'); } }
Модели / Place.php
class Place extends Eloquent { public function photos() { return $this->morphMany('Image', 'of'); } }
Здесь Person может загружать один mugshot
и много photos
, а на Place может быть много photos
. Проблема в том, что когда я создаю mugshot
на Person, он сохраняет это в таблице images
в базе данных:
id: 1 of_id: 1 of_type: Person
Он не сохраняет факт, что это mugshot
а не photo
, поэтому, когда я $person->mugshot
его, $person->mugshot
может иногда возвращать одну из $person->photos
и наоборот.
Есть ли (a) лучший способ сделать это, чем создать 2 ссылки на одной и той же Модели, или (б) способ фактически заставить этот способ работать?
Сейчас нет встроенного способа. Возможно, в Laravel 4.1 это должно привести к полной переработке полиморфных отношений.
Добавьте свойство Image
в Image
, затем определите, where
условия для отношений:
public function mugshot() { return $this->morphOne('Image', 'of')->where('type', 'mugshot'); } public function photos() { return $this->morphMany('Image', 'of')->where('type', 'photo'); }
Не забудьте задать type
Image
вами Image
. Или, как я сделал, скрыть эту логику внутри модели.
Вот мой код (я использую PHP 5.4 с короткой записью массива):
Образ:
namespace SP\Models; class Image extends BaseModel { const MUGSHOT = 'mugshot'; const PHOTO = 'photo'; protected $hidden = ['type']; public function of() { return $this->morphTo(); } }
Человек:
namespace SP\Models; use SP\Models\Image; class Person extends BaseModel { public function mugshot() { return $this->morphOne('SP\Models\Image', 'of') ->where('type', Image::MUGSHOT); } public function photos() { return $this->morphMany('SP\Models\Image', 'of') ->where('type', Image::PHOTO); } public function saveMugshot($image) { $image->type = Image::MUGSHOT; $image->save(); $this->mugshot()->save($image); } public function savePhotos($images) { if(!is_array($images)) { $images = [$images]; } foreach($images as $image) { $image->type = Image::PHOTO; $image->save(); $this->photos()->save($image); } } }
Где-то в контроллере / службе:
$person->savePhotos([$image1, $image2]);