Extending Eloquent Models in Laravel (use different tables)

19,755

1. Yes, it makes perfect sense to have all the common functionality in a parent model.

2. Basically each Eloquent model will handle the data from its own table defined in the protected $table variable. You can override the parent variable to set a separate table for all the different child models. Laravel Table Names

For example if you use the getId() method on a RefinanceLead instance it will return the id from refinance_lead table. If you use it on a PurchadeLead instance it will retirn the id from purchade_table

class Lead extends Model
{
    public function getId() {
       return $this->id;
    }
}

class RefinanceLead extends Lead
{
     protected $table = 'refinance_leads';
}

class PurchaseLead extends Lead
{
    protected $table = 'purchase_leads';
}

3. I don't know what are your exact needs, but in general I'll suggest making the Lead class abstract and so you don't associate a table for it. Use it only to separate common functionality, relations, etc... Of course as it was suggested in the comments, implementing an interface is always a good idea.

abstract class Lead extends Model implements LeadContract
{
   // class body
}
Share:
19,755
jackel414
Author by

jackel414

I'm a software developer based in the LA area who does a bit of everything, but lots of PHP (mainly Laravel and CakePHP) and AngularJS.

Updated on June 07, 2022

Comments

  • jackel414
    jackel414 about 2 years

    I’m building a Laravel application that involves tracking different types of leads. For example, there are Refinance leads and Purchase leads.

    Since the leads share a lot of information and functionality, but not all, my thinking was to create a Lead class, which extends Laravel’s Model class, and then a RefinanceLead class, which extends the Lead class.

    So I’d have:

    class Lead extends Model
    {
        // shared lead stuff
    }
    
    class RefinanceLead extends Lead
    {
        // stuff specific to refinance leads
    }
    

    My questions are:

    1. Does this strategy make sense?
    2. If it does, how is Eloquent going to handle the data? Will I have a leads table and a refinance_leads table?
    3. Will a new instance of the RefinanceLead class utilize anything in the leads table?

    I’ve had trouble answering this question via the documentation, but if I missed where this is explained, please let me know. Thanks.

  • jackel414
    jackel414 about 8 years
    Thanks iivannov - this is really helpful! Quick follow up (which will hopefully stay within the scope of the original): we're hoping to have a unique identifier across all lead types; a universal 'lead id'. Do you have a recommendation for how to tackle that? If Solar Leads and Refinance Leads have normal, independent tables, then obviously the standard id field will overlap.
  • Antonio Pantano
    Antonio Pantano over 7 years
    I'm trying to learn Laravel so I apologize if my question is silly, but if you want to fetch all the leads can we use leads::all() and retrieve all RefinanceLeads and PurchaseLeads all together ? I suspect I'm saying a foolishness since the data are stored in 2 different tables. How could that be doable anyway? Suppose we have a Product model and than we extend it with ComputerProduct and CarProduct, is there a way to get all products without querying 2 tables ?
  • Hassan Saqib
    Hassan Saqib about 3 years
    Hi, this is really awesome answer. Can I make abstract class and contract of user while using User in authentication guard? Like Coach extend User implements UserContract and like two or three more models? without implementing different Guards and retaining default auth?
  • Popnoodles
    Popnoodles almost 3 years
    This is not working for me. Laravel is ignore my protected table and trying to use what it guessed from the parent model name
  • iivannov
    iivannov almost 3 years
    @Popnoodles I checked and it should be working with the latest version too. If you experience any problems it would be better to provide more information about your framework version, model structure and the code that doesn't work, so we can help. If you think it's too much information - create a new question and share it here in the comments.
  • Popnoodles
    Popnoodles almost 3 years
    @iivannov thanks. it does work. I had referenced the parent class in the parent class by mistake instead of using get_called_class, e.g. new Lead() as opposed to new get_called_class() and Lead::someMethod() instead of get_called_class()::someMethod()