I basically have two models (dog and cat) of the same type: pets. The table pets joins all dogs and cats in the database. Now I would like to be able to find a specific pet through the pet id in the PetController. Like so:
$pet = Pet::findOrFail($id); // returns a dog or cat
Tables structure:
┌──────────────┐ ┌───────────┐ ┌───────────┐
│ pets │ │ dogs │ │ cats │
├──────────────┤ ├───────────┤ ├───────────┤
│ id │ │ id │ │ id │
│ related_type │ │ name │ │ name │
│ related_id │ │ eye_color │ │ tail_size │
└──────────────┘ └───────────┘ └───────────┘
Pets table:
┌────┬──────────────┬────────────┐
│ id │ related_type │ related_id │
├────┼──────────────┼────────────┤
│ 1 │ dog │ 1 │
├────┼──────────────┼────────────┤
│ 2 │ dog │ 2 │
├────┼──────────────┼────────────┤
│ 3 │ cat │ 1 │
└────┴──────────────┴────────────┘
I have searched the Laravel docs but none of the relationships seem to fit for this problem. Only the polymorphic relationship would work the other way around, so that I could access the pet model through the dog- or cat-id. But I am looking for a solution that work the other way around. Is there any kind of relationship without needing to use nasty if-else in the PetController manually?
Thank you!
A one-to-one polymorphic relationship is a situation where one model can belong to more than one type of model but on only one association. A typical example of this is featured images on a post and an avatar for a user. The only thing that changes however is how we get the associated model by using morphOne instead.
with() function is used to eager load in Laravel. Unless of using 2 or more separate queries to fetch data from the database , we can use it with() method after the first command. It provides a better user experience as we do not have to wait for a longer period of time in fetching data from the database.
BelongsTo is a inverse of HasOne. We can define the inverse of a hasOne relationship using the belongsTo method. Take simple example with User and Phone models. I'm giving hasOne relation from User to Phone. class User extends Model { /** * Get the phone record associated with the user.
"MorphTo" is used to define the relationship from a one-to-one or one-to-many polymorphic table to whichever model or models it is linked to. https://laravel.com/docs/5.7/eloquent-relationships#one-to-many-polymorphic-relations.
You can define a polymorphic relationship between these 3 models like this
Pet Model
public function related(){
$this->morphTo();
}
Dog Model
public function pets(){
$this->morphMany('App\Pet', 'related');
}
Cat Model
public function pets(){
$this->morphMany('App\Pet', 'related');
}
Now fetch it like this
$pet = Pet::findOrFail($id)->related;
dd($pet); //you will get either cat or dog
Easy create
$dog = Dog::create(['name'=> 'dog1', 'eye_color' => 'gray']);
$dog->pets()->create();
Check details here https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With