How can you update multiple models and their relations at the same time?
For example:
EditPost is a model with a editor() relation belongsTo User model.
Now lets say I have to update the editor in all the EditPost objects with original_post_id
EditPost::where('original_post_id',4)->get()
Possible Solutions
a. To do it by referring the user by ID instead of by the Model User
EditPost::where('original_post_id',4)->update(array('editor_id',3));
b. To do it by a foreach and saving each model
However
Neither of these appeals to me as they don't gel in general with the object concept of Eloquent or they would mean doing multiple updates instead of one.
I was wondering if Eloquent itself had a more elegant solution
You don't specify the other end of the association, but I assume you are looking for something like this?:
$user = User::find(3)
EditPost::where('original_post_id', 4)->editor()->associate($user)->save();
Related
In my application, a model Device has a many-to-many relationship with model Task.
A combination of Device and Task could be assigned to a various number of model User.
example: Device A has a Task Check something and this should be done by User Frank and Steven.
From my point of view, this should be a "standard problem", but so far I could not find a proper solution.
Right now, I use following workaround:
a) added an unique ID id to the device_task pivot table
b) query id from the pivot table
c) create a new table device_task_user which contains user_id and device_task_id
b) use query builder to get/add users
But I am really not happy with this approche.
Would it be possible, that the pivot table also extends Model and then have a one-to-many relationship with User?
Or would you suggest to add a json colum to the pivot table and store the users there?
Any idea would be very welcome!
Would it be possible, that the pivot table also extends Model
Yes, it's possible. From the docs:
If you would like to define a custom model to represent the intermediate table of your relationship, you may call the using method when defining the relationship. All custom models used to represent intermediate tables of relationships must extend the Illuminate\Database\Eloquent\Relations\Pivot class
You also can create a new hasMany() and belongsTo() relationships between Task and Device models and use them as well as existing belongsToMany relationship. And you'll need to define a new relationship between pivot model and User model to be able to get data by device, task or user.
Modify many-to-many relationship to hold an extra field user_id
class Device extends Model
{
public function tasks()
{
return $this->belongsToMany(
Task::class,
'device_task',
'device_id',
'task_id'
)->withPivot('user_id');
}
}
And when updating do like this in controller
$device->tasks()->attach([$taskId]=>['user_id']=>$userId);
And of-course you need DeviceTask model and also a has-many relationship between User model and DeviceTask model to get user's task
I'm struggling with Eloquent relationships in my Laravel project.
I have a 'user' table and a 'user_lines' table in my database. The 'user_lines' table has a' user_id' field that corresponds to the 'id' field in 'users', in a classic master-detail relationship.
The User model has a hasMany relationship to the UserLine model. The UserLine model has a belongsTo relationship to the User model.
In my application I have a user form that contains several userlines. During form submits those userlines can be added, altered or deleted. So far I find myself iterating the submitted userlines and manually creating, updating and deleting the userlines. I feel I'm missing out on the attach/detach/sync methods Eloquent provides but I can't seem to get them to work.
$user->lines()->attach or $user->lines()->sync
gives me an exception telling me these are undefined methods on Illuminate\Database\Query\Builder.
$user->lines()->createMany($lines)
works but that just creates new lines, it does not update existing lines and delete removed lines.
The attach, detach and sync methods are for the many-to-many relationship and not for one-to-many. So, you need to iterate over lines and add or edit them one by one.
Your tables relationships isone-to-many and for attaching to such relationships you should use save, saveMany or create methods.
for updating you could do something like this:
$user->lines()->where('field',$something)->update($array);
The attach, detach and sync methods are for the many-to-many relationships and not for one-to-many.
Groundwork
I have a database design (snipped to relevant portions) like so:
records
entities
people
where no proper relationship exists between the tables, but rather records is extended by entities is extended by people by sharing the same id.
I have my Eloquent models similarly defined so that Record is extended by Entity is extended by Person.
Goal
Record and Entity are abstract and I want to simply use Person and other models at that level in the hierarchy.
Problem
How do I 'link' Record and Entity to Person to make this all work seamlessly? I don't think relationships is appropriate. I assume it's related to something like this:
protected __construct() {
parent::__construct();
}
I suggest you still create a model for Person, Entity, and Record, and link them together with "belongsTo" relationships. (add entity_id column to "People" table, add "record_id" to "Entities" table).
If you are only working with the Person model, you could add a "saved" model observer to create the entity and record entries whenever you create a Person, and tie them all together with a global id.
http://laravel.com/docs/eloquent#model-observers
If you did it this way, you could access the person's entity and record field by doing something like:
$person->entity->fieldName
$person->record->fieldName
All that being said, this seems way too complicated. I would only have one table for People and store all the person's data there. imo.
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.
I have a model Animal in Yii which has two relations, mainRace and secondaryRace, both of them being an instance of the Race model.
How can this be translated into the relations array of Animal model aswell as in the Race model?
Looks like you'd need a many to many relationship, so you'll need one more table (animal_race).
See the Yii Relational page for more info on how to setup a MANY_MANY
Edit: if you're wanting to limit the animal to only two races, then you'd probably want to have a main_race_id / secondary_race_id in the Animal model (assuming an animal can only ever be in two races, what if the animal is entered in multiple events?).
And then you'd use a BELONGS_TO setup. That way you can easily find all the animals for a given race using a HAS_MANY relationship.