This one has had me stumped all day!
I have the following models:
Pump class
class Pump < ApplicationRecord
has_one :control, as: :equipment
accepts_nested_attributes_for :control
Pump Schema
class CreatePumps < ActiveRecord::Migration[5.1]
def change
create_table :pumps do |t|
t.references :property, foreign_key: true, null: false
t.string :name, default: 'Pump', null: false
t.timestamps
end
end
end
Control class
class Control < ApplicationRecord
belongs_to :equipment, polymorphic: true
Control Schema
class CreateControls < ActiveRecord::Migration[5.1]
def change
create_table :controls do |t|
t.belongs_to :device, foreign_key: true, index: true
t.integer :position, index: true
t.references :equipment, polymorphic: true, index: true
t.belongs_to :control_type, foreign_key: true, index: true
t.timestamps
end
end
end
I'm trying to update the association between a Control and a Pump. The following works:
[439] pry(main)> Pump.first.update!(control: Control.find(62))
.
.
.
=> true
But the following doesn't and I can't figure out why.
[438] pry(main)> Pump.first.update(control_attributes: {id: 62})
(0.4ms) BEGIN
(0.4ms) ROLLBACK
ActiveRecord::RecordNotFound: Couldn't find Control with ID=62 for Pump
with ID=1
from /usr/local/bundle/gems/activerecord-
5.1.5/lib/active_record/nested_attributes.rb:584:in
`raise_nested_attributes_record_not_found!'
The context is that I have a form for a Pump and when editing my Pump, there's a list of Controls in a select drop-down. I would just like to choose which Control is associated with the pump.
Update1: Answering a question from below
[468] pry(main)> Pump.first.update(control_attributes: {id: 62})
Pump Load (1.0ms) SELECT "pumps".* FROM "pumps" ORDER BY "pumps"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.3ms) BEGIN
Control Load (0.4ms) SELECT "controls".* FROM "controls" WHERE "controls"."equipment_id" = $1 AND "controls"."equipment_type" = $2 LIMIT $3 [["equipment_id", 1], ["equipment_type", "Pump"], ["LIMIT", 1]]
(0.3ms) ROLLBACK
ActiveRecord::RecordNotFound: Couldn't find Control with ID=62 for Pump with ID=1
from /usr/local/bundle/gems/activerecord-5.1.5/lib/active_record/nested_attributes.rb:584:in `raise_nested_attributes_record_not_found!'
Pump.first.update(control_attributes: {id: 62})
Rails's nested attributes does't work this way! The code above means:
Find a control which's id is 62, and it's equipment_type should be "Pump", and it's equipment_id should be Pump.first.id, then update with extra params, which you did not provided.
You got this error because in the first step, the control with id 62, it's equipment_id isn't Pump.first.id
Like, to update name of the control which's id is 60, belongs to Pump.first, in correct association:
Pump.first.update(control_attributes: {id: 60, name: "xxxx"})