Ruby on rails 覆盖rails中的嵌套属性

Ruby on rails 覆盖rails中的嵌套属性,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,在rails中重写嵌套属性方法时会发生什么。比如说, class Order has_many :line_items accepts_nested_attributes_for :line_items def line_item_attributes=(attr) # what can I do here. end end class LineItem belongs_to :order end 在上述代码中 在line\u item\u attributes=

在rails中重写嵌套属性方法时会发生什么。比如说,

class Order
  has_many :line_items
  accepts_nested_attributes_for :line_items

  def line_item_attributes=(attr)
   # what can I do here.
  end
end

class LineItem
  belongs_to :order
end
在上述代码中

  • line\u item\u attributes=
    方法中,我可以添加/修改/删除订单的行项目吗
  • 如果调用
    @order.save(params)
    ,何时调用
    line\u items\u attributes=
  • 是的,你可以。就打电话
  • 为集合关联分配嵌套属性(:行项目、属性、质量分配选项)

    当你完成的时候

    还要检查源代码:
    #文件activerecord/lib/active_record/nested_attributes.rb,第263行

  • 从文档中:
  • 拯救

    对模型的所有更改,包括销毁标记为 销毁,当 将保存父模型。这发生在事务内部 由父级保存方法启动。看见 ActiveRecord::AutosaveAssociation

    我认为覆盖这个方法不是一个好主意。保存后,我会将您的代码添加到

    使用别名 在Rails 4中,您可以重写并调用
    super

    在早期版本中,您可以使用Ruby的
    别名

    class Order
      has_many :line_items
      accepts_nested_attributes_for :line_items
    
      # order of arguments is new_name, existing_name
      alias :original_line_items_attributes= :line_items_attributes=
      def line_items_attributes=(attrs)
       modified_attributes                 = my_modification_method(attrs)
       self.original_line_items_attributes = modified_attributes
      end
    
    end
    
    我遇到了同样的问题。 通过一些努力,我解决了这个问题。 也许有人会遇到同样的问题,所以我把答案贴在这里

    attr\u writer
    覆盖
    line\u项目的原始设置器
    然后调用super,将结果放入默认setter

    class Order
      attr_writer :line_items
      has_many :line_items
      def line_items=(value)
        # manipulate value
        # then send result to the default setter
        super(result)
      end
    

    这里的
    super
    不是更好的选择吗?我想你的意思是第一个答案:在这种情况下,不是,因为它通过eval创建方法,因此,如果你调用super,它将覆盖你的方法。如果可能的话,super将是更好的选择。在edge Rails(Rails 4)中,您可以重写一行\u item\u attributes=setter并调用super,但在Rails 3.2.x中,您目前不能只调用super。这个问题我有个特例。我得到的修改只是,输入包含一个类似
    {id:4738979}
    的键,这是一个非rails系统的id,内部称为
    public\u id
    。所以我这样做:
    attrs[:id]=LineItems.where(public\u id:attrs[:id])。first.id
    。。。这不是很优雅,我几乎可以肯定rails为我提供了这样一种方式。有什么想法吗?(目前我正在按照您的建议进行覆盖)请问,我是否可以自己构建项目,而不调用
    super
    ?除了建造物品,这是否提供了任何其他魔法?