I have many to many relationship .
in the blade code i sent many items with actionID[]
and then i insert them like this:
$detailsAttribute->actions()->sync(Input::get('action_id'));
now I want to update that model.
i used this same statement
$detailsAttribute->actions()->sync(Input::get('action_id'));
it creates the new actions but didn't remove the older ones. In other words, when I edit the model $detailsAttribute, I delete the older actions and I select many new ones.
my question is how to update the model considering removing the non selected actions?
sync() method will remove all those items from pivot table if they are not present in your
Input::get('action_id') array. If they are not removed that means you are also passing old data in the new array. var_dump your Input and see what kind of array you are getting.
Related
I have 2 Doctrine Entities with many-to-many relations. When I edit the first entity I want to be able to select the checkboxes that have the data from the 2nd entity to establish the joins for particular entry.
It works fine on creating a new Entry (using Array Collection), but when I want to edit an Entry - it adds the ones that I have selected without removing the previous choice (unchecking).
Which way would be the correct way to do that and how?
Remove all the Join table data for the Entry that is being updated,
then set the new data. (How can I remove it from the join table that
is not an Entity?)
Pass all the data from the 2nd Entity and remove
those that aren't checked (seems super-clumsy?)
Some other way I am not aware of?
I am not using Symfony, just Doctrine.
Doctrine makes working with the many-to-many associations quite easy. Your associations are stored into an ArrayCollection class that has some methods that can help you. First of all, check all the available methods for the ArrayCollection here (Doctrine API - ArrayCollection)
In your case, I'd use this approach: use the clear method on your ArrayCollection that contains the relationship with the 2nd entity and populate it again with the checked elements. After this, call the flush method on the entitymanager.
Another approach consists in filtering your collection (with the filter method) for getting a brand new ArrayCollection that contains only the elements that are checked. Like the first approach, associate this new collection to the relationship's ArrayCollection and call the flush method on the entitymanager.
I have mulutiselect option enabled in select html code, my frontend look like this:
For example if user unselect some option and select other how can I update it in database, any idea?
If you have ManyToMany relationships between say Group and Project you can use sync() method to maintain association as below,
$group->projects()->sync([$projId1, $projId2]);
Above will remove all previous association between current group($group) and projects and associates newly supplied projects i.e. $projId1, $projId2.
If you want to maintain previous associations pass false as a second argument in sync() as below,
$group->projects()->sync([$projId1, $projId2], false);
Above code will maintain previous Group and Project association and will also associate passed projects.
I have a set of 'clients' and they are displayed in a GridView. 'Clients' can not be deleted by the average user, only marked for deletion. However I would like it so they are not displayed in the list once they are marked for deletion.
I am using Yii2, and the soft deletion table contains has three columns that concern the data 'foreign_table', 'foreign_column' and 'foreign_value'. It is set up like so as I do not want to delete data from the 'Clients' table unless it is needed.
How would I go about filtering the results of the GridView?
Would I use $model->search?
I believe you could use $model->search to filter the result, provided that the following steps are already done:
You have a means of flagging rows marked for deletion: state or status.
In the search() method of the Model represented by $model you specify the criteria used to filter the result by using: $criteria->condition = 'status=1 OR status=2';.
Depending on your database and how you have decided to flag or marked-as-deleted, you may have to modify $criteria. You may even chose to use $criteria->with to include foreign tables.
So you have a table where you save references to items that should be considered as deleted.
I think it could be reasonable to override find() of the Client class since there could be many cases where you want to ignore the marked-as-deleted clients. If so you could write the appropiate query in find(). As a nice side effect the GridView will show only the not marked-as-deleted clients automatically.
To get the marked-as-deleted clients you would need an extra methode, of course, if this is needed at all (you could want to delete them in the db directly and you don't need php code for this). But most of the time you don't need them. So you could filter them out by overriding the find method.
I'm stuck in a problem and I can't find a solution to this, it's annoying me.
I've two tables, one called contacts and the other one called phonebooks and they are linked with a third table called *contacts_phonebooks*, this is a many-to-many relationship summarize below:
contacts: id (pk)
phonebooks: id (pk)
contacts_phonebooks: contactid (fk), phonebooksid (fk)
Pretty simple and clear, and it works.
I'm using Laravel 4 and Eloquent ORM, everythings works fine when I've to fetch it, insert it and delete it but when I need to update a contact I fail miserably. I've a form that has a number of checkboxes that represent all the phonebooks (every checkbox has phonebook[] as name) so when you check one of those the phonebook id will be saved in the *contacts_phonebooks* with the contact id.
The problem is that this is not true! I mean when I run this code:
$contact = Contact::find($id);
$contact->contact_name = Input::get('newCName');
$contact->contact_surname = Input::get('newCSurname');
$contact->contact_email = Input::get('newCEmail');
$contact->contact_phone = Input::get('newCPhone');
$contact->contact_birth = Input::get('newCDate');
$contact->phonebooks()->sync(Input::get('phonebook'));
if($contact->save())
{
return "TEST DONE?";
}
It deletes every row in *contacts_phonebooks* associated with the contact id and save only the new one checked... This is weird I know, I try to explain it better.
I want to update Mr.x and he actually is in "Stackoverflow" phonebook, I want to add him in "Nerd" phonebook so I click on update and I selected "Nerd", the other one is already selected.
When I update him the system deletes the "Stackoverflow" link and save ONLY the "Nerd" phonebook (with the code above) this things driving me crazy because Laravel 4 Doc says that you should use the sync() method in order to update a many-to-many relationship.
I don't how how to solve it, I hope you will understand what's my problem.
Cheers.
The documentation says "The sync method accepts an array of IDs to place on the pivot table. After this operation is complete, only the IDs in the array will be on the intermediate table for the model:"
So what I think you are probably looking for is attach().
$contact->phonebooks()->attach(Input::get('phonebook'));
Then you will have to use detach() to remove him from the other.
As stated in the docs: The sync method accepts an array of IDs to place on the pivot table.
Your pivot table should be named
contact_phonebook
and it specifies that in Laravel's documentation.
I have two tables with a ManyToMany relationship. I needed to add some extra fields to this relationship, so I created a new entity that has a ManyToOne relationship with each of the two tables. The issue I'm having is with removing the relationship entity. I don't want to remove entries in either of the two tables, I just want to remove the relationship. What I've done to set up the relating entity is pretty much described here:
Doctrine2: Best way to handle many-to-many with extra columns in reference table
To remove the relationship, I've tried removing the relating element from each of the two other table entries, and then setting the reference to those tables to null in the relating entity. That doesn't seem to work; Doctrine tries to execute a query to update the entry in the relating table and set both the foreign keys to null. I would expect it to remove the entry in the relating table, if all references to it have been removed.
Let me know if you'd like to see my entities, or if this makes enough sense as it stands.
Actually, deleting the entity that acts as "join-table" does the trick.
Nothing should be cascaded.
So assuming you have a relation like
User <- UserGroup -> Group
You just need to remove the UserGroup entity.
If you remove User or Group, and you have set cascade persist operations correctly, also UserGroup will go. You can also use orphanRemoval to avoid having UserGroup assigned to different User or Group elements.