简体   繁体   中英

Laravel polymorphic hasMany relationship

From Laravel's docs, the model polymorphism is defined as follows:

Polymorphic relations allow a model to belong to more than one other model on a single association

Sounds like it's designed to work with belongsTo instead of hasMany side. Here's a scenario that I want to achieve:

In my system, there are many project types, each projec type will have its own invoice field layout. Let's say we have a Project model that has a type field, whose value could be contract or part-time . We have another two tables called ContractInvoice and PartTimeInvoice to define their respective field layout, both of these invoice tables have a project_id referencing a project record. What I want to do is I want a universal interface to retrieve all invoices given a project, something like $project->invoices .

Current solution

I can't figure out how to achieve this via polymorphism. So what I am currently doing is kind silly, using a switch statement in my invoice() method on Project model class:

switch ($this->type) {
    case 'contract':
        $model = 'App\ContractInvoice';
        break;
    case 'part-time':
        $model = 'App\PartTimeInvoice';
        break;
}

return $this->hasMany($model);

I feel like there must be a better way to do this. Can someone please shed some light?

I don't see how a polymorphic relationship would be beneficial in this case. If you had different project type models and a single invoices table, then the invoices could morphTo the projects. But as you've described it, the switch statement sounds like it is adequate. You could achieve the same means using when conditionals like:

public function invoices()
{
    return $this->when($this->type === 'contract', function () {
        return $this->hasMany(ContractInvoice::class);
    })->when($this->type === 'part-time', function () {
        return $this->hasMany(PartTimeInvoice::class);
    });
}

The type attribute on the Project model and the separate invoice tables are defining a rigid relationship between them, which goes against the idea of polymorphism. Think likes for comments and posts .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM