Laravel use case for *has many through* relationship - php

I have a table participants where each participant belongs to a conference, which is an entry in the table conferences. Further, each participant can provide one answer which are stored in the table answers.
Now, I need a query which gets all the answers from all participants which belong to the current conference.
In particular, I would like to paginate the results, thus I am hoping for a more sophisticated approach than to simply fetch all answers and then check if they belong to a participant in this conference.
To be clear, my tables store basically the following information:
participants - id, conference_id
conferences - id
answers - id, participant_id

You could use HasManyThrough.
I think the example in the Laravel Doc fits perfect to your case.
Laravel Doc example

You can use hasMany and hasOne relation ship of Laravel Eloquent Model, and add more constraint when you use Eloquent Relation Ship query (As Laravel document say All Eloquent Relation Ship is query builder, so you can add constraints using where) to get results you expect.

Related

Laravel - Update models relations to another model

I have a many-to-many relationship between an incident model and a Patient model. An incident can have many patients and a patient can be involved in many incidents.
Should it occur that a user creates duplicates of a patient model we want to be able to merge those two patient models into one. This means that I want to move the incidents that patient 1 is involved in to patient 2 including additional attributes that are sitting on the pivot table.
I've tried something as simple as
Casualty::where('patient_id', $patientOne->getKey())->update(['patient_id' => $patientTwo->getKey()]);
But this doesn't work. Using the updateOnExistingPivot() method would mean I need to iterate over every incident for patient 1 and run a separate DB query to update the patient to patient 2.
I've also tried updating the record like this
$patientOne->incidents()->update(['patient_id' => $patientTwo->getKey()]);
This also doesn't work because there is no patient_id column on the incidents table.
How can I achieve this or am I doing something wrong?
Not sure if I understood you, you want to group more patients into the same accident? You could go with the belongsToMany relation and make one pivot table. Then, when you want to update the data simply use the sync method.
You can also try storing them with json_encode() in one column which will hold only users ID's and later on retrieve them.
Sorry, can't give more info since the question is not described that well.

establish a relationship among a table with many different table

i have a table (piovt table) that links the invoice id and the service id, but the service id does not come from one table but comes from different tables. here is an example of that.
i tried use polymorphic relations but i only get the last recored not all recoreds related to the invoice
so how to get the services from invoice table?
You can check the Has One Through relationship.
Laravel documentation states "The "has-one-through" relationship defines a one-to-one relationship with another model. However, this relationship indicates that the declaring model can be matched with one instance of another model by proceeding through a third model."
You can read more and get code examples here
Laravel has one through relationship

Laravel/Eloquent - Modeling a HasOne relationship via a BelongsToMany relationship

Say I have four tables:
users
groups
activities
group_activities
Where a group can have any number of activities and an activity can belong to any number of groups through their intermediate table group_activities, and a user belongs to one group via users.group_id. I want to correctly model a relationship between users and activities so that a user can have any one activity, but only if the group that user belongs to has a relation to that activity.
HasOneThrough doesn't seem to work here, since the group the user is related through has multiple activities. HasManyThrough doesn't work since the user can only have one.
I want to properly model this relationship so that it can be picked up for selection automatically via a Nova relationship field, but I'm struggling to figure out exactly how I would do so. My first thought is a HasOneThrough relation with some set of subqueries, but I can't quite piece together where to start.
How would I do this, or conversely, is it possible via Eloquent's automatic relationship system at all?
To ensure we are on the same idea of your relationships:
The relationship between Groups and Activities is a Many To Many relationship (Many To Many - Larvel Documentation).
The group_activities table is the pivot table.
The relationship between users and groups is a One To Many relationship One To Many - Larvel Documentation and the inverse of it One To Many (Inverse) - Larvel Documentation.
To actually answer your question:
If you want to use a shortcut from users to their activities, the Has Many Through is the correct way. If a group can have arbitrary many activities, and a user belongs to one group, the user will be associated to these arbitrary many activities through the group -hence Has Many Through. Note that this is not really a separate relationship though, it's just a convient shortcut.
If you wan't to associate a user with a single Activity directly, you need to to this via a separate One to Many relationship between Users and Activities.
I'm not entirely sure if I interpret your question correctly, so the following is just an assumption, but do you want to ensure a user can only be associated to an activity thats also associated with the user group? So to restrict possible activites by group? If that is the case, you'd simply need to check if the selected activity is in the activities associated with the users group:
With your relationships set up like this:
class User {
public function activity(){
return $this->belongsTo('App\Activity');
}
public function possibleActivities(){
return $this->hasManyThrough('App\Activity','App\Group');
}
}
you can check and associate activities like this:
if( $user->possibleActivities()->contains( $activity ) ){
$user->activity()->associate($activity);
}

Delete/update laravel pivot table entry by id

I've got a database structure as follows where item A is in a many to many relationship with B.
This is a true many to many, so:
Item X (object in table A) relates to Y (object in B) multiple times.
Using the laravel attach() function easily adds these records. However, I need to update and delete these items.
The detach() and sync() methods seem to not be appropriate. They assume only one pivot table entry between one record and another record.
If I detach() then ALL items are deleted. That is not what I want.
So the main point of my question:
If I have the id of the pivot table record, how do I delete/update it... given that detach doesn't work as expected.
Or put another way:
How can I interact with a pivot table object directly?
You can use newPivotQuery().
Something like that:
Parent::relation()->newPivotQuery()->where('id', $someId)->delete();
The where() and delete() statements will apply to the pivot query.
Thanks to all,
#devk has pointed out a good solution to the problem if you have the child objects available. I've upvoted this answer because it is true and useful for future reference.
Unfortunately, at this particular point I only have the many-to-many id, so i am answering this with a "No - there is no specific way to access the pivot table by id" using the Pivot or similar objects.
However: to be clear, this can still be done in eloquent using the DB class.
DB::table('many-to-many-lookup')
->where('id', $id)
->take(1)
->delete();

Difference between HABTM relationship and 2 $belongsTo relationship with a third model

I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.

Categories