Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I have a content type with a field collection. I have set up a node migration and a field collection migration. I have 'track_changes' => 1 on both. When I run the import the first time everything works great. I get my node data as well as the field collection data showing correctly. If I edit the source data on the node migration and run the import again it updates the node but the field collection data is deleted. Any suggestions?
Comments
Comment #1
briand44 CreditAttribution: briand44 commentedWhen migrate calls node_save during an update the $node object being passed doesn't contain the field collection data. Therefore, when field_collection_field_update() is triggered it thinks that the field collection data has been removed so it deletes it.
I came up with a workaround by writing a prepare function in my migration that loads the original node object and adds the field collection data from it to the $node object being passed to node_save. This probably isn't an ideal fix but is working for now.
Comment #2
briand44 CreditAttribution: briand44 commentedThis seems more like a Field collection issue so moving it there.
Comment #3
mscalone CreditAttribution: mscalone commentedI had the same problem and the workaround proposed on #1 worked fine with some minor modifications:
Comment #4
alcroito CreditAttribution: alcroito commentedThanks a lot, this also helped me fix the issue of updating a node, and not losing the field collection values!
Comment #5
vlad.dancer@mscalone. Thanks. But there is an error "Call to undefined method MyImportMigration::prepare()", so I think parent::prepare($node, $row); is redundant.
Comment #6
Dru18 CreditAttribution: Dru18 commentedI am having the same issue. The first time it works but if I run the exact same migration again, it wipes out the field collection data. Obviously this is a terrible bug nobody seems to care about. I tried the above source codes but the destination class doesn't call Prepare method if it is updating; it doesn't work, either. As #1 said 2 yrs ago, the node save function is triggered with empty objects. At my wit's end, I feel really frustrated.
UPDATE:
After spending some amount of time, I was able to complete the process. In case there's someone who goes through the same. This is for continuing migration process.
If there is any attached field collections or entity references to a node, you have to map those data. In my case, I attache the original (current) data and let the following (dependent) migration takes care of updating.
And collect the mapping data before migration saves the data.
I tested it by assigning array and map it in order to avoid the delimiting process; this doesn't seem to work.
Hope this helps someone.
Comment #7
rodrigoaguileraHi
I just ran into this issue.
Can you post the method getMyFieldCollectionList so the solution is a bit more clear.
Thanks
Comment #8
nanakI just implemented it that way, works perfectly
Comment #9
oana.hulpoi CreditAttribution: oana.hulpoi as a volunteer commentedThanks, @nanak! Your solution works great! Old field collections remain on the host entity and new ones are added (if it is the case) on a subsequent import (update).
Comment #10
BramDriesenSorry to bump this issue. But the solution Nanak proposed does not work when you also have translations in your entity.
It will keep the field collections, but it will add ALL field collection id's to the current item you're migrating. So let's say you're migrating a field on the english entity and you have a translated version in French. It will link all the French items as well on the English entity. On the plus side it does keep the french values as well in the French entity. If I found a migration solution to this I'll post it in a new comment.
EDIT: So still the best way to do it is to use the prepare function. In here you can write a field query to load the original field data and store it again in the entity. A tutorial about this can be found here: http://timonweb.com/posts/loading-only-one-field-from-an-entity-or-node-...
My use case:
Comment #11
nanakTo support entity translation, you need to pass an array in your field mapping instead of a string, and add another field mapping 'your_field:language', with an array of languages to import, in the same order than the field above.
But if you need to import a multivalue and multilanguage field, you'll have to use prepare()