Shihab EK
Shihab EK

Reputation: 70

Multiple Table for Single Eloquent Relationship

I Have One Message Model and both Admin and User can create a message. But for Admin and User have separate model called Admin and User.

Message model have a column called 'created_by' and which stores creator's id. Now the question is how can I make relationship with Message and creator. I need to get the creators details from 'Admin' model or from 'User' Model.

Currently I'm using a method inside Message model as below.

public function creator(){
    if(User::find($this->created_by)){
      return User::find($this->created_by);
    }else{
      return Admin::find($this->created_by);
    }
}

But it doesn't support Eager Loading feature in Laravel.

Thanks for your help.

Upvotes: 2

Views: 508

Answers (2)

SEYED BABAK ASHRAFI
SEYED BABAK ASHRAFI

Reputation: 4271

You should use polymorphic relationship in this case. As stated in laravel doc

A polymorphic relationship allows the target model to belong to more than one type of model using a single association.

By doing this, you can get messages from both Admin and User models.

Define the following method in Message model.

use Illuminate\Database\Eloquent\Model;

class Message extends Model

{
    /**
     * Get the owning messageable model.
     */
    public function messageable()
    {
        return $this->morphTo();
    }
}

And add following columns in the migration file:

$table->unsignedBigInteger('messageable_id');
$table->string('messageable_type');

Then, define the below method in Admin model.

class Admin extends Model
{
    /**
     * Get all of the admin's messages.
     */
    public function messages()
    {
        return $this->morphMany('App\Message', 'messageable');
    }
}

And in User model.

class User extends Model
{
    /**
     * Get all of the user's messages.
     */
    public function messages()
    {
        return $this->morphMany('App\Message', 'messageable');
    }
}

Upvotes: 5

jgetner
jgetner

Reputation: 703

Laravel has Accessor they are great for this sort of thing. In your model add a method such as below. this will take the created by id and search up the admin or user and then return those results. So now when you make your message query you just access the user such as $message->created_by->username; You can learn more about mutators in here https://laravel.com/docs/7.x/eloquent-mutators#defining-an-accessor

 public function getCreatedByAttribute($value)
 {
    $user = User::where('id', $value)->first();
    if(!is_null($user)){
        return $user;
    }

    $admin = Admin::where('id', $value)->first();
    if(!is_null($admin)){
        return $admin;
    }

   return null;

 }

Upvotes: 0

Related Questions