how do I make relationships for 4 tables including pivot table - laravel

I have many to many relationships. Imagine I have 3 tables. Something like this :
users.
roles.
role_user.
(This example is also provided in laravel's docs).
Now I'm doing this : $user->roles() which returns roles with Pivot attributes . but what I actually want to do is move forward and also get the appropriate data from the 4th table. something like this $user->roles()->types(); and the difficult thing is that this types() belongs to pivot table.
Do you know how to do this kind of thing ? where Do I write types() function?

Assuming your "Roles" model has the relationship set you may try
$user->roles()->with("types")
Source docs: https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

Related

Laravel models, database and pivot tables question

Hello I am working with Laravel,
I have to create two simple models, let's say Stores and Books.
Stores can have one or multiple Books and Books can belong to many Stores.
Of course I will use a many to many relationship, with a pivot table.
Books the can have different prices depending the store.
I think a separate table can only complicate things, in my mind the pivot table associating books and stores should have a price column, but pivot tables only contains store_id and book_id.
Should I create a book_prices and associate it with books and to stores? What is the best approach?
You are free and able to set other attributes on your pivot table. You can read more about it in the docs.
https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns
You have to define the relationship accordingly, the following should clarify how this works. In this example you use the many-to-many relationship and add the price column to every retrieved pivot model.
public function books()
{
return $this->belongsToMany(Book::class)
->withPivot('price')
}
For example, you are able to access the pivot column in a loop like this
foreach ($shop->books as $book)
{
echo $book->pivot->price;
}
You can define additional columns for your pivot table in the migration for the pivot table, and then when defining the relationship use withPivot to define the additional columns so they come through in the model:
return $this->belongsToMany(Book::class)->withPivot('price');
(Adapted from the Laravel documentation, see https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns)
Depends on the complexity of your case, but yes, you have two options for it. Let's say that the pivot table is called as book_store:
Directly adds price column to book_store. This is obviously the simpler option. The drawbacks are:
The history of the price changes isn't logged. You'll have to create another table for logging if you want to keep this history information.
Changes made to price will directly change the price of the related book_store record. Meaning that a price is being updated "live" e.g users cannot update the price now but "publish" it some time later just like this example in the doc.
Create a new, different table to store the price. This may seems relatively more complex, but it may also be more future-proof.
Basically, you get 2 things that you miss in the first option above.
Don't think too much about book_store being a pivot table. One way to see it is like this: book_store IS a pivot table from books and stores tables viewpoints, but it's also just a normal SQL table which could relate to any other tables using any kind of relationships.
If you want to implement this, make sure to create a primary-key in the book_store table.
Alast, it all depends on what you need. Feel free to ask if you need more insight about this. I hope this helps.

Laravel - How to relate two collections like Eloquent method "belongsToMany" and "with"

How can you combine two collections, one being the collection of parent items together combined with your collection of child items?
I would like something like using the method with and belongsToMany,but in this scenario I cannot use both methods correctly because one table is in another schema and the pivot table is in another schema.
Area::with('permissoes')
->where('sistema', '<>', 'S')
->get()
Most Eloquent eagerloads are done with separate queries that just use an IN statement on keys from the previous one. Pivot tables are the exception. It sounds like you need to explicitly tell the Model relation what database your pivot table is in. See my answer here: belongsToMany relationship in Laravel across multiple databases

Conditional Relationship in laravel Eloquent

Let I have 3 table named user, admin, post
My post table structure is
-id
-poster_id
-poster_type //if value is 1 then poster_id will be releted with user table. if value is 2 then poster_id releted with admin table.
Now How writte belongsTo relationship with two table based on poster_type value
I want to do in Post model like this
public function Author(){
return $this->belongsTo('User', 'poster_id')->where('poster_type', '1') //poster_type is the field of post table.
}
First of all, you are talking about a Polymorphic relationship, supported by eloquent. You should take a look at the documentation.
http://laravel.com/docs/eloquent#polymorphic-relations
Second, you are mixing Eloquent relationships with special data recovery functions, and that's something you should avoid. I suggest you split the relationship itself from the data recovery function.
Also, if you want to go one step further, keep the relationship in the model, and split the data recovery functions into a repository object.

Dynamically set the table name in a "has many" relation model

In my database schema, I have multiple tables that hold generic data for objects, for instance I have a user table and a user_data, post table and post_data, and so. these *_data tables all hold a foreign key to the object and a pair of key-value. now in my laravel models I would like to have a single data models for these tables (rather than a model for every single one) and represent the has_many relation in a dynamic way where somehow I can define the table name according to the parent model. I think the parent model would have something like:
return $this->hasMany('data');
but I don't know how to express the inverse relation nor how to tell laravel which *_data table to use. so my question is, is it possible? and if so, how?
You have two options.
Either create a model for each data_* table and use the relation as stated with $this->hasMany('data'); and $this->belongsTo('User'); in the data table and the user table.
Or you can use Polymorphic relations, I personally prefer the polymorphic relations solution, more neat.

GAS ORM many-many relation with attributes

I'm using CodeIgniter and I'm starting to work with gas orm.
One of my m-n-relationship-tables using a composite key has also some additional attributes to the releation.
For Example:
Table teams, Table employees, and a m-n table which binds them together + adding the attribute role
Is it possible to get the attribute using GAS ORM?
Yes, it is possible.
Simply create a new relationship in one of the two tables you are going to link with the pivot table that refers to the pivot table itself as a has_many relation. (But dont do the linking stuff in the model file, eg:
ORM::has_many('\\Model\\User\\Role')
instead of
ORM::has_many('\\Model\\User\\Role => \\Model\\Role')
See http://ellislab.com/forums/viewreply/1050559/ for exact the same question.

Resources