Search code examples
ruby-on-railsactiverecordhas-and-belongs-to-many

ActiveRecord no longer finding duplicate IDs in array and saving for has-and-belongs-to-many relationship, Rails 4.2.8


I upgraded from rails 4.2.0 to rails 4.2.8 this evening. The only major pain has been figuring out why my array of item_ids can no longer have a duplicate when saving in my items_payments HABTM relationship.

This works just fine in 4.2.0... but now, for instance, if I assign @payment.item_ids = [14,14] before saving the payment, rails and activerecord throw this error: Couldn't find all Items with 'id': (14, 14) [WHERE "items"."id" IN (14, 14)] (found 1 results, but was looking for 2)

If the array of ids does not have a duplicate, then it saves just fine. I need the same item_id to appear more than once, though, in the case that a user buys more than one instance of an item. How do I make it so that this is ok again? I know this may have everything to do with deprecated finders... but how do I do this the right way in 4.2.8 and eventually rails 5.0?

Edit: Here is the code in my controller, model, and schema. I didn't change any of this when upgrading rails... and when saving an array of item ids such as [14,12,5] it will work just fine. It just won't allow me to save with a duplicate item id anymore, like [14,14]

Controller:

items_array = []
items.each do |item|
    quantity = params[:payment][:item_quantity]["#{item.id}"][:quantity]
    quantity = quantity.to_i
    quantity.times do
        items_array.push(item.id)
    end
end

@payment.item_ids = items_array

Schema:

create_table "items_payments", id: false, force: :cascade do |t|
  t.integer "item_id"
  t.integer "payment_id"
end

Payment Model:

has_and_belongs_to_many :items

Item Model:

has_and_belongs_to_many :payments

Lastly, my console output:

(0.2ms)  SELECT COUNT(*) FROM "items" WHERE "items"."id" IN (14, 14)
  CACHE (0.0ms)  SELECT COUNT(*) FROM "items" WHERE "items"."id" IN (14, 14)
Completed 404 Not Found in 133ms (ActiveRecord: 8.6ms)

ActiveRecord::RecordNotFound (Couldn't find all Items with 'id': (14, 14) [WHERE "items"."id" IN (14, 14)] (found 1 results, but was looking for 2)):
  app/controllers/payments_controller.rb:196:in `block in create'
  app/controllers/payments_controller.rb:172:in `create'

Solution

  • I think this is just an underlying bug in ActiveRecord for Rails 4.2.8. If you are slowly upgrading to Rails 5, just upgrade on up to Rails 4.2.9 and this issue completely goes away...