Rails 5: Model.children.update_attributes equivalent of Model.children.new + Model.save

231 Views Asked by At

I am trying to update mulptile list_items that belong to a list, but do so without saving to the database immediately, and then when they are all temporarily updated, save them. My code looks like this

  old_length = @list.list_items_count
  new_length = @body['list_items'].length
  @body['list_items'].each_with_index do |list_item, i|
    if old_length < new_length
      @list.list_items.new(item_id: list_item['item_id'], position: i+1)
    else
      @list.list_items[i].item_id = list_item['item_id']
    end
  end
  @list.save!

The model.children.new part works, but not the model.children.attributes. The real issue is that there is a migration that prevents list_ids and item_ids to be duplicated:

add_index :list_items, [:list_id, :item_id], unique: true

Before this migration I would run:

@list.list_items[i].update_attributes!(item_id: list_item['item_id'])

However, since update_attributes saves immediately to the database, the restricting migration doesn't allow some changes to be made. These changes are when I change item_ids that are already ListItems and I just want to switch them around. Example:

Before:
#<ListItem id: 342, list_id: 57, item_id: 333, position: 1, created_at: "2018-02-02 18:10:45", updated_at: "2018-02-02 18:10:45">
#<ListItem id: 343, list_id: 57, item_id: 444, position: 2, created_at: "2018-02-02 18:10:45", updated_at: "2018-02-02 18:10:45">

After:
#<ListItem id: 342, list_id: 57, item_id: 444, position: 1, created_at: "2018-02-02 18:10:45", updated_at: "2018-02-02 18:10:45">
#<ListItem id: 343, list_id: 57, item_id: 333, position: 2, created_at: "2018-02-02 18:10:45", updated_at: "2018-02-02 18:10:45">

In the example above, 333 and 444 are just switching places, but the migration throws an error because one is done before the other, and not simultaneously.

0

There are 0 best solutions below