skip to Main Content

I have three different model in my Laravel project; Convoy, User, Driver. Driver is a different model than User because of they can not authenticate. Whatever, there is also one more model: Address.

I am storing address values on the addresses table, Address model. Columns are given below;

addresses : addressable_type (int), addressable_id (int)

There is also one more model named as Type, it stores type of everything in the project. For example it stores authorization types (Super User, User, Admin, etc…), eloquent model types which is given under Models path (AppModelsUser, AppModelsDriver, etc…), payment types etc…

I think you got it what am I gonna ask to you but let’s continue. If you figure out, I did not set the type of addresses.addressable_type as varchar(255). Normally, polymorphed model can read AppModels* format but instead of this I want to store id of eloquent model from types.id table.

addressable_type    | 10 // this refers to `types`.`id`
addressable_id      | 1
country             | 225
state               | 2175
city                | 108155
address             | NULL
status              | 1
created_at          | 2024-08-31 14:50:13
updated_at          | 2024-08-31 14:50:13

id                  | 10
type                | AppModelsConvoy // so this is record in the types table
label               | 2
created_at          | 2024-08-31 14:50:12
updated_at          | 2024-08-31 14:50:12

Convoy.php given below;

class Convoy extends Model
{
    use HasFactory;
    protected $guarded = [];

    public function address() : MorphOne
    {
        return $this->morphOne(Address::class, 'addressable');
    }
}

Address.php given below;

class Address extends Model
{
    use HasFactory;
    protected $guarded = [];

    public function addressable() : MorphTo
    {
        return $this->morphTo();
    }

    public function status() : BelongsTo
    {
        return $this->belongsTo(Status::class);
    }
}

HomeController.php given below;

public function convoys() : View
    {
        $test = Convoy::with('address')->find(6);
        dd($test);
        return view('convoys', compact('convoys'));
    }

Result;

AppModelsConvoy {#1228 ▼ // app/Http/Controllers/HomeController.php:50
  ...
  #relations: array:1 [▼
    "address" => null
  ]
  ...
}

I can’t get any kind of address.

2

Answers


  1. you can update the AppServiceProvider and add this

    use IlluminateDatabaseEloquentRelationsRelation;
    
    Relation::morphMap([
            10 => AppModelsConvoy::class,
            11 => AppModelsUser::class,
            12 => AppModelsDriver::class,
        ]);
    
    Login or Signup to reply.
  2. I would recommend that you use a polymorphic relationship as it is intended.
    You would have the following as your polymorphic relationship:

    <?php
    class Address extends Model
    {
        public function parent(): MorphTo
        {
            return $this->morphTo();
        }
    }
    

    I would then further recommend you then use a trait to attach this to any models that will have an address associated to them (this will help prevent duplicated code)

    <?php
    trait HasAddress {
        public function address(): MorphOne
        {
            return $this->morphOne(Address::class);
        }
    }
    

    Then inside your Convoy, User, Driver or anything else that will have an address you can simply add the following into the beginning of it.

    use HasAddress;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search