Laravel 4, Multiple polymorphic relationships from one model

I am trying to establish polymorphic relationships in Laravel 4 so that I have one Image class that handles everything related to loading, disconnects, etc., and then use it with several different models. This is great until I try to create multiple links from the same model.

For example, I currently have something like this:

Models / image.php

class Image extends Eloquent { public function of() { return $this->morphTo(); } } 

Models / Person.php

 class Person extends Eloquent { public function mugshot() { return $this->morphOne('Image', 'of'); } public function photos() { return $this->morphMany('Image', 'of'); } } 

Models / Place.php

 class Place extends Eloquent { public function photos() { return $this->morphMany('Image', 'of'); } } 

Here a person can upload one mugshot and many photos , while Place can have many photos . The problem is that when I create a mugshot in Person, it saves this in the images table in the database:

 id: 1 of_id: 1 of_type: Person 

It does not preserve the fact that it is a mugshot , not a photo , so when I pick it up, $person->mugshot can sometimes return one of $person->photos and vice versa.

Is there (a) a better way to do this than creating 2 links on the same Model, or (b) a way to really make this work?

+6
source share
1 answer

There is no built-in way right now. Perhaps in Laravel 4.1, which was supposed to completely rewrite polymorphic relationships.

Add a type property to Image , then define where conditions for the relationship:

 public function mugshot() { return $this->morphOne('Image', 'of')->where('type', 'mugshot'); } public function photos() { return $this->morphMany('Image', 'of')->where('type', 'photo'); } 

Remember to set type to the Image you are creating. Or, as I did, hide this logic inside the model.

Here is my code (I am using PHP 5.4 with a short write array):

Picture

 namespace SP\Models; class Image extends BaseModel { const MUGSHOT = 'mugshot'; const PHOTO = 'photo'; protected $hidden = ['type']; public function of() { return $this->morphTo(); } } 

Person

 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); } } } 

Somewhere in the controller / service:

 $person->savePhotos([$image1, $image2]); 
+20
source

Source: https://habr.com/ru/post/957580/


All Articles