1

这个让我难过了一整天!

我有以下型号:

泵类

class Pump < ApplicationRecord
  has_one :control, as: :equipment
  accepts_nested_attributes_for :control

泵模式

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

控制类

class Control < ApplicationRecord
  belongs_to :equipment, polymorphic: true

控制模式

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

我正在尝试更新ControlPump之间的关联。以下作品:

[439] pry(main)> Pump.first.update!(control: Control.find(62))
.
.
.
=> true

但以下没有,我不知道为什么。

[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!'

上下文是我有一个 Pump 表单,在编辑我的 Pump 时,选择下拉列表中有一个控件列表。我只想选择与泵关联的控件。

Update1:​​从下面回答一个问题

 [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!'
4

3 回答 3

0
Pump.first.update(control_attributes: {id: 62}) 

Rails 的嵌套属性不能这样工作!上面的代码意味着:

找到一个 id 为 62 的控件,它的设备类型应该是“Pump”,它的设备 ID 应该是 Pump.first.id,然后使用您没有提供的额外参数进行更新。

您收到此错误是因为在第一步中,ID 为 62 的控件的设备 ID 不是 Pump.first.id

就像,要更新 id 为 60 的控件的名称,属于 Pump.first,正确关联:

Pump.first.update(control_attributes: {id: 60, name: "xxxx"}) 
于 2018-03-21T02:03:18.407 回答
0

当您用于链接模型时,如果提供的属性没有参数accepts_nested_attributes_for,它将创建新记录。当属性带有参数id时,它将更新与父记录链接的现有记录。id

ActiveRecord::RecordNotFound: Couldn't find Control with ID=62 for Pump with ID=1:此错误表明没有找到具有上述 IDControl的对象的记录。Pump

您可以为泵添加新的控制记录:

Pump.first.update(control_attributes: { attribute1: 'attribute1_value' } )

这将创建与具有 IdControl的对象关联的新记录。现在您可以再次更新它,如下所示:Pump1

Pump.first.update(control_attributes: { id: 1, attribute1: 'updated_attribute1_value' } )

请注意,id新创建的控制记录被视为1

请通读文档以获取更多详细信息。

希望这可以帮助 !

于 2018-03-20T07:45:44.883 回答
0

您可以覆盖模型中的嵌套属性设置器方法,以便它也直接更新外键列。

# pump.rb
def control_attributes=(attributes)
  if (new_control = Control.find_by(id: attributes[:id]))
    self.control_id = new_control.id
  end

  super
end

注意:直接分配关系时要小心(即),因为如果它是使用导致删除记录self.control = new_control的选项定义的 has_one 关联,则可能会导致一些意想不到的副作用。:dependent

于 2021-10-25T09:57:37.513 回答