首页 > 解决方案 > 如果表列在更新时发生更改,Assign_attributes 仅分配子 attr_accessor 值

问题描述

这是设置

class Order
  has_many :items
  accepts_nested_attributes_for :items
end

class Item
  belongs_to :order
  attr_accessor :discount # this is NOT a table column, just a virtual attribute I want to be able to assign
end

假设我有一个现有的订单@order。我注意到如果我要尝试从模型中分配discount孩子,这只有在孩子的其他一些属性发生变化时才有效。ItemOrderItem

@order.assign_attributes({"items_attributes"=>[{"id"=>40, "discount"=>"test"}]})
@order.items.first.discount
=> nil

@order.assign_attributes({"items_attributes"=>[{"id"=>40, "discount"=>"test", "admin_notes"=>"hello"}]})
# where admin_notes is a table column for Item
@order.items.first.discount
=> "test
@order.items.first.admin_notes
=> "hello"

是否有快速设置更改或更改此设置?attr_accessor即使没有属性发生变化,我也希望始终分配属性?

标签: ruby-on-railsrubyattr-accessor

解决方案


我看到您最初的问题要求能够使用attr_accessor,但似乎不可能。我只能通过删除attr_accessor.

看起来attr_accessor实际上具有相反的行为,即在使用时使属性不可访问而不是允许它accepts_nested_attributes_for。也许是一个错误?文档没有提供任何示例。只要您params.permit在 Controller 端进行操作,在没有attr_accessor.

class Order
  has_many :items
  accepts_nested_attributes_for :items
end

class Item
  belongs_to :order
end

从 Rails 控制台调用它:

@order = Order.find(1)
@order.assign_attributes({"items_attributes"=>[{"id" => 1, "discount_cents" => "234"}]})
@order.save

#  Order Load (0.4ms)  SELECT "orders".* FROM "orders" WHERE "orders"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
#  Item Load (0.3ms)  SELECT "items".* FROM "items" WHERE "items"."order_id" = $1 AND "items"."id" = $2  [["order_id", 1], ["id", 1]]
#   (0.1ms)  BEGIN
#  Item Update (0.3ms)  UPDATE "items" SET "discount_cents" = $1 WHERE "items"."id" = $2  [["discount_cents", 234], ["id", 1]]
# => true
#   (5.8ms)  COMMIT

@order.assign_attributes({"items_attributes"=>[{"id" => 1, "discount_cents" => "789"}]})
# => nil
#  Item Load (0.4ms)  SELECT "items".* FROM "items" WHERE "items"."order_id" = $1 AND "items"."id" = $2  [["order_id", 1], ["id", 1]]
@order.items.first.attributes
# => {"order_id"=>1, "id"=>1, "discount_cents"=>789}

希望能为您的问题提供解决方案:)


推荐阅读