Laravel 5 Inheritance of the model - returning parent data when receiving child mode

So, I have this crazy idea that is related to Laravel and model inheritance. I would like to set up a single-parent model set, but when I ask for a child model, I would like to return the data. For example, I would have a contact model that is parent:

Contacts: id, first_name, last_name, image 

Then I will have a series of contact types that inherit from contacts. Each of these child models will have its own set of fields (i.e. for members I need to know when they joined, etc., but for volunteers I may need to know if they have a modern first aid certificate ) Here are some examples:

 Members: contact_id, joined_on, birthday, medical_concerns Volunteers: contact_id, current_first_aid, interests Staff: contact_id, pay_rate 

I would like to do something like:

 $members = \App\Member::all(); 

and return the contact data AND, as if everything was a single line, for example:

 +---+------------+-----------+-------+------------+------------+------------------+ |id | first_name | last_name | image | joined_on | birthday | medical_concerns | +---+------------+-----------+-------+------------+------------+------------------+ | 1 | Fred | Bloggs | null | 2015-01-01 | 1993-10-22 | false | | 2 | Jim | Phillips | null | 2016-04-30 | 1987-09-22 | true | +---+------------+-----------+-------+------------+------------+------------------+ 

And to make it a little more complicated, I would like all the relationships that apply to parents to work for the child. So I could do something like this:

 $members = \App\Member::find(1)->phone 

And even if the Member model does not have a relationship defined for the Phone model, it will return the phone associated with the contact, because the parent has this relationship.

I would also like to indicate columns that are not related to the child when retrieving data, and Laravel does not throw an error:

 $members = \App\Member::all(['first_name','last_name','joined_on']) 

I came across overriding the Eloquent model and writing my own version of all and finding methods that work, but it looks like I might have to redefine all the methods to make it work, and maybe it will work more than just leave Eloquent and looking for another (or my own custom solution).

So, I think, my questions are: is there a โ€œsimpleโ€ way to do this with Laravel, or am I trying to get him to do what he never intended to do?

+5
source share
2 answers

I think you can do like this:

 $members = \App\Members::with('contact')->all(); 

Of course, your model of participants had to determine the relation of belonging to the contact model.

0
source

Is there an โ€œeasyโ€ way to do this with Laravel, or am I trying to get him to do what he never intended to do?

Yes.

The eloquent cannot manage inheritance in this way. It might be better to implement polymorphic relationships .

However, redefining only this bit seems to serve your purpose:

 abstract class ContactSubclass extends Contact { protected $with = 'parent'; public function parent() { return $this->belongsTo(Contact::class, 'contact_id'); } public function newQuery() { $contactTable = (new Contact())->getTable(); $thisTable = (new static())->getTable(); $builder = parent::newQuery(); $builder->join($contactTable, "$thisTable.contact_id", '=', "$contactTable.id"); return $builder; } public function newFromBuilder($attributes = [], $connection = null) { $model = parent::newFromBuilder($attributes, $connection); if ($model->parent) { $model->setRawAttributes(array_merge($model->parent->getAttributes(), $model->getAttributes()), true); } return $model; } protected function getRelationshipFromMethod($method) { if (method_exists(parent::class, $method)) { return $this->parent->getRelationshipFromMethod($method); } return parent::getRelationshipFromMethod($method); } } 

You have Member and other subclasses extending this class (or add these overrides in each class that extends Contact ).

(I have not tested it completely, try it. Also, it will not handle direct downloads directly, try to find something to override if you want to support it.)

0
source

Source: https://habr.com/ru/post/1262458/


All Articles