Laravel - Eloquent relation - many-to-many - get intermediate table columns - laravel

I have a question about Laravel Eloquent Relations.
I have the following table situation:
Table guests:
id
name
...
Table landing_pages:
id
name
...
A guest can have several landing pages. And a landing page will have multiple guests.
So I thought, I can use a many-to-many relationship there and I created a new table
Table guests_landing_pages:
id
guest_id
landing_page_id
...
I would be able to use this the following way:
In guest Model I can do this, to create the many-to-many relationship:
public function landing_pages()
{
return $this->belongsToMany(\App\Models\LandingPage\LandingPage::class, 'guests_landing_pages','landing_page_id','guest_id');
}
... and the other way round in landing_page model.
But actually the table guests_landing_pages contains more data than just the guest_id and landing_page_id relation.
There are several other fields in it:
Table guests_landing_pages:
id
guest_id
landing_page_id
identifier_token
max_persons
answer
...
My question is now, how can I realize this best. If I would use the many-to-many relation as described above, I will not be able to access the fields in the intermediate table, won't I?
Or will the best solution to this to create a GuestLandingPages model with all the fields and create hasMany relations to/in both?

Laravel Eloquent has features for retrieving intermediate columns.
public function landing_pages()
{
return $this->belongsToMany(\App\Models\LandingPage\LandingPage::class, 'guests_landing_pages','landing_page_id','guest_id')
->withPivot('max_persons', 'answers');
}

Related

Laravel Relationships with 3 tables problem

I don't understand how to connect three tables in Laravel.
users> id, ...
groups> id, ...
group_user> id_group, id_user
I want to return all groups to me auth()->user()->groups.
Thanks in advance.
According to your explanation, group_user table holds many-to-many relationship between Group and User model. In case of a many-to-many relationship, you actually don't need a GroupMember model. This kind of table which holds many-to-many relationship is called pivot table. Read more from the Official Documentation
The first argument is the Model you are relating to, the second one is the name of the pivot table, and third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to
User.php
class User
{
public function groups()
{
return $this->belongsToMany(Group::class,'group_user','id_user','id_group');
}
}

Nested eloquent relationship

I just started my first laravel project today and stumbled upon this confusing situation,
I intended to use eloquent relationship instead of manually joining tables on query. So here it goes...
I have 3 tables which are users , tbl_instruments_taught , tbl_instruments
users table does not hold any of the table's ID,
tbl_instruments_taught - holds the id of user and intruments
Note: user can teach multiple instruments
Now, I implemented a hasOne on my other result set but I dont think hasOne works on this one. I read about belongsToMany but as I try implement it, it seems like every minute, it gets confusing.
Any idea?
I think you are looking for pivot table and relation many to many.
You have users table, instruments table (user has many instruments and one instrument could belong to many users) and user_instruments pivot table. Here db model:
And then add belongsToMany relationship in User and Instrument model (with specified pivot table). Like so:
//IN USER MODEL
public function instruments()
{
return $this->belongsToMany('App\Models\Instruments', 'users_instruments', 'user_id', 'instrument_id');
}
//IN INSTRUMENT MODEL
public function users()
{
return $this->belongsToMany('App\Models\Users', 'users_instruments', 'insrument_id', 'user_id');
}
Now you can reach instruments/users data through laravel relations/eager loading.

Laravel 5.5 many to many relationship with an intermediate table

Please help,
I have these relationship in laravel between ITEMS, SUPPLIERS and PURCHASE_ORDERS
As ITEMS and SUPPLIERS has many to many relationship, I created an intermediate table between them, called ITEM_SUPPLIER.
Now I need to make a many to many relationship between PURCHASE_ORDERS and the intermediate table ITEM_SUPPLIER.
How do I make the relationship?
Should I create an intermediate table between them, what's the best way to name it?
Add a model for pivot table ItemSupplier whth extra column id which extends Pivot
use Illuminate\Database\Eloquent\Relations\Pivot;
class ItemSupplier extends Pivot
{
public function purchaseOrder()
{
return $this->belongsToMany(PURCHASE_ORDERS::class, item_supplier_purchase_order);
}
}
As you see you need to create a new item_supplier_purchase_order pivot table and add the relationships
class PURCHASE_ORDERS extends Model
{
public function purchaseOrder()
{
return $this->belongsToMany(ItemSupplier::class, item_supplier_purchase_order);
}
}
Add id column to the item_supplier and create ItemSupplier model for the pivot table. Then create a new item_supplier_purchase_order pivot table and two belongsToMany() relationships between ItemSupplier and PurchaseOrder models.
Also, don't forget to use cascade deleting to delete records from new pivot table when a related record is deleted from item_supplier pivot table.

Laravel delete all belongsToMany relations in belongsToMany relation

I have a Tournament model which contains a belongsToMany relationship with a Session model:
class Tournament extends Model{
public function sessions(){
return $this->belongsToMany(Session::class, 'tournament_has_sessions');
}
}
Then my sessions model contains a belongsToMany relationship with the User model:
class Session extends Model{
public function users(){
return $this->belongsToMany(User::class, 'session_has_users');
}
}
Now when I delete a Tournament, I want to delete all sessions and all information in the session_has_users table with it.
I have tried:
$tournament->sessions()->with('users')->delete(); -- < This
$tournament->sessions()->delete();
$tournament->users()->detach();
$tournament->delete();
But it does't work. The data in the session_has_users table persists
I realize i could do something like this:
DB::table('session_has_users')->whereIn('session_id', $this->sessions()->pluck('id'))->delete();
But is there a more efficient/handy (or even alternative if not more efficient) way to accomplish this?
Using RDBMS Referential Actions on the Foreign Key
In the database schema, you should define the foreign key with the ON DELETE CASCADE action. This will automatically delete the related records when the referenced id is deleted.
(See dbudimir's answer for the example lines from a Laravel migration file)
Using Eloquent to Detach All Related Models
If you aren't using foreign keys or your database lacks the support for referential actions, you can use this:
$tourament->sessions()->sync([]);
The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table:
https://laravel.com/docs/5.5/eloquent-relationships#updating-many-to-many-relationships
Providing an empty array should then remove all the relations.
In the table 'tournament_has_sessions' you can set onDelete('cascade') like this
$table->integer('tournament_id')->unsigned()->nullable();
$table->foreign('tournament_id')->references('id')->on('tournaments')->onDelete('cascade');
$table->integer('session_id')->unsigned()->nullable();
$table->foreign('session_id')->references('id')->on('sessions')->onDelete('cascade');
And when delete tournaments automaticly deleted all records in this table
you can use any of these:
$tourament->sessions()->detach();
or
$tourament->sessions()->sync([]);
or you can define the foreign key with the ON DELETE CASCADE like the answers above

Eloquent relationship with 3 tables

I'm new to Stack Overflow and Laravel.
I try to develop a variable profilesystem in Laravel and I got 3 tables ('User', 'User_Fields', 'Fields').
The structure of the Fields table is following:
The structure of the user_fields table is following:
The User table is the standard table which came with Laravel 5
Now I want to get all fields from user_fields depending on which user is selected or logged in. If the user_field doesn't exists, the model should return null or create a new record for the user_field.
I tried a lot of "solutions" which came with eloquent like (hasManyThrough, belongsToMany) but I don't get the result I wanted.
Is there any solution with relationship methods?
Thanks for your help, and sorry for my bad english :/
You should be using the belongsToMany()->withPivot() to retrieve the intermediate table columns. Your user_fields is your pivot table so on your user model you should have:
class User extends Model
{
public function fields()
{
return $this->belongsToMany(Field::class, 'user_fields')->withPivot('value');
}
}
Then you can access your values for a user by:
$user = User::find($id);
foreach($user->fields as $field) {
$field->pivot->value;
}

Resources