Custom Many-to-Many Relationship - laravel

I have 3 entities:
Institution
Branch
Address
Institution & Branch will have many Addresses, so in order to not create two child models for storing the address of each entity, I want to create a pivot table which will have these columns as primary key: entity_id, address_id, entity_name. With this approach I will store the relationship of all addresses for Institution and Branch.
This is my code in entities_addresses pivot table
Schema::create('entities_addresses', function (Blueprint $table) {
$table->integer('entity_id')->unsigned();
$table->integer('address_id')->unsigned();
$table->string('model_name', 50);
$table->primary(['entity_id','address_id','model_name']);
Next, in Address Model I have the following code:
public function institutions()
{
return $this->belongsToMany(Institution::class, 'entities_addresses', 'entity_id', 'address_id');
}
Next, in Institution model I have the following code
public function buildings()
{
return $this->hasMany(Building::class);
}
I believe I need to add somewhere else which is the "custom" relationship, beacuse now I'm recieving this error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'addresses.institution_id'
So, my questions are:
Where do I have to specify the custom relationship?
It's a better approach to create an intermidate model?
I will have to customize the use to be attach and detach methods? In which place I willhave to do it?
Regards

Related

Laravel - is there a library that lets me do a hasManyThrough relationship where my models PK is either value

Is there a library where I am able to use a pivot table that points to the same model twice (i.e User) where I can have the PK as either column 2 or 3 for something like a friending or associating system?
Code Example
migration
Schema::create('friends', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('requestor_id');
$table->unsignedBigInteger('requested_id');
$table->boolean('accepted')->default(0);
});
model
public function friends(){
return $this->[LibraryMethod](Friend::class, 'requestor_id', 'requested_id')->where('accepted', 1);
}
So then I could then either look at 'requestor_id' or 'requested_id' for my PK and get the PK of an associated User.
Ideally this should also work with eloquent functions.
I recognise that friends isn't the best example as you could have a handshake-like system, but for simple associations (i.e, between products) something like this would be pretty useful.

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');
}
}

How do you combine the following three tables with eloquent in laravel?

How to combine 3 Many to Many tables with eloquent in the laravel
Hi Friends, please help me,
How do you combine the following three tables with eloquent in laravel?
The following table structure and figures:
(https://i.stack.imgur.com/BfISA.jpg)
Member table structure
{member_id: primary key, name, created_at, updated_at}
List table structure
{list_id: primary key, member_id: foregn key, price_id: foreign key, created_at, updated_at}
Price table structure
{price_id: primary key, name_price, created_at, updated_at}
Can you give me sample source code for view.blade, controller and model.
Thank you, your answer is very meaningful
in your member model add relationship function list(). Then in your list model add relationship function price then use below code
app\Member.php
public function list(){
return $this->hasMany('App\List', 'member_id');
}
app\List.php
public function price(){
return $this->hasMany('App\Price', 'price_id');
}
in your controller
$result = Member::with(['list.price'])->get();
it will give you a member list with list and price table data.

HasOne Relationship Differences between v5.5 and v5.6 - no longer the same?

I have a Person model with demogographic information, Orgs model with organization information and an OrgPerson model that is effectively a pivot table with additional fields. I've crated OrgPerson to extend Model instead of Pivot because it worked better with my setup.
--- Edit: table structures ---
Table: person (Model: Person)
PK: personID
(other demographic fields)
defaultOrgID (FK -> orgID) // the org that will be displayed/referenced by default
// changeable by user with multiple orgs
Table: organization (Model: Org)
PK: orgID
(other org-demographic fields)
Table: org-person (Model: OrgPerson -- functionally a pivot table)
PK: personID, orgID
(other combo-demographic fields for the person with respect to the org)
--- End of table structures edit ---
I acknowledge that the OrgPerson model is the capture of a many-to-many relationship. However, I need to be able to grab the "combo-demographic" data (stored in the OrgPerson record) for the person related to the defaultOrgID.
Because a Person can belong to multiple Orgs, I want the orgperson record for $this person but for the "default" Org as stored in $person->defaultOrgID.
My Person model had the following relation defined in v5.5 and it returned what I wanted via $person->load('orgperson') or via eager loading.
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'personID', 'personID')
->where('orgID', $this->defaultOrgID);
}
Running code like:
$person = Person::find(x);
$person->load('orgperson')
Returns a Person model with a non-null orgperson model in the relationships list.
After upgrading to v5.6 and performing some testing, I'm finding that this relation is not populating. I haven't gotten it to populate in any of my testing and I cannot find any reason why it would be different.
add a migration to give orgperson table a primary key
Schema::table('orgperson', function (Blueprint $table) {
$table->bigIncrements('id');
});
so you can do something like this
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'defaultOrgID', 'personID')
}

Laravel relationships: hasManyThrough a model with on an pivot table

I have 3 models in Laravel:
Item
ModifierGroup
Modifier
An Item can have many ModifierGroups via an intermediate table:
public function modifierGroups()
{
return $this->belongsToMany(
'App\ModifierGroup',
'menu_item_modifiers',
'item_id',
'group_id'
)->using('App\MenuItemModifier')
->orderBy('position', 'ASC')
->withPivot('position');
}
A ModifierGroup has many Modifiers:
public function modifiers()
{
return $this->hasMany(
'App\Modifier',
'group_id',
'id'
)->orderBy('position', 'ASC');
}
My question is whether it's possible to have a function on the Item that gets to the Modifiers, going through the ModifierGroup (and its pivot)? HasManyThrough doesn't seem to fit with an pivot table involved or does it?
It's possible with a BelongsToMany relationship by "skipping" the ModifierGroup table:
public function modifiers() {
return $this->belongsToMany(
'App\Modifier',
'menu_item_modifiers',
'item_id',
'group_id',
null,
'group_id'
);
}
This problem can be solved using pivot tables, but not in the way that you are using them. As I assume you have three tables - each associated with your models (Item, ModifierGroup, Modifier), you haven't set up pivot functionality as you don't actually have pivot tables. To do this you would require one table to link Item to ModifierGroups and another to link ModifierGroups to Modifier.
To start, lets create the tables using Artisan:
php artisan generate:pivot Item ModifierGroup
now, we have a table called item_modifier_group (I believe?). This table should have two columns, item_id and modifier_group_id. These are the keys Eloquent will use to connect to the items and modifier_groups tables. Now, in our query we can access and item's modifier groups by using the following query:
public function modifierGroups()
{
return $this->belongsToMany('App\ModifierGroup');
}
This means that when you call $item->modifierGroups() you will get a collection of all modifier groups having an id of $item->id.
This process can then be repeated for the ModifierGroups to Modifiers relationship:
php artisan generate:pivot ModifierGroup Modifiers
Now define the modifiers method in the ModifierGroup model:
public function modifiers()
{
return $this->belongsToMany('App\Modifier');
}
Now we have our pivot tables set up, and our relationships defined in one direction (just add similar methods to models to get Items via Modifiers)
The final piece of the pie is Eager Loading (it's amazing). Get item, with modifiers through the appropriate groups like so:
Item::with('modifierGroups.modifiers')->findOrFail('id');
Now there are other ways you could have gone about this problem, and some may even be more valid, however the huge benefit to doing it this way is the flexibility. You now have a way to connect Items, ModifierGroup and Modifiers with pivot tables and with a simple eager loaded query, can get any collection combination you deem necessary. Hope this helped! This is definitely the longest solution I've ever written on here...
For future reading I recommend:
Eager Loading - Nested Eager Loading
Defining Relationships - Many-to-Many

Resources