使用parent.send(关联).build动态添加嵌套字段而不是reflect_on_association(关联).klass.new

时间:2013-09-24 11:24:20

标签: ruby-on-rails nested-forms nested-attributes railscasts

我正在使用simple_form的fields_for,并使用Ryan Bates(Railscast)提出的link_to_add_fields方法动态添加字段。

我遇到的问题是

f.object.class.reflect_on_association(association).klass.new

,用于实例化其他字段的模型,创建一个完全空的记录(order_id没有设置),因此我的委托方法导致错误。

如果您改为使用

send(:line_items).build

要实例化新记录,它已经设置了父级id

# order.rb
class Order < ActiveRecord::Base
    has_many :line_items

    def price_currency
        "USD"
    end
end

# line_item.rb
class LineItem < ActiveRecord::Base
    belongs_to :order

    delegate :price_currency, :to => :order
end

# rails console
> order = Order.last # must be persisted
> line_item1 = order.class.reflect_on_association(:line_items).klass.new #=> #<LineItem id: nil, order_id: nil, created_at: nil, updated_at: nil>
> line_item2 = order.send(:line_items).build #=> #<LineItem id: nil, order_id: 1, created_at: nil, updated_at: nil>

> line_item1.price_currency #=> RuntimeError: LineItem#price_currency delegated to order.price_currency, but order is nil
> line_item2.price_currency #=> "USD"

我的问题:为什么Ryan Bates使用

f.object.class.reflect_on_association(association).klass.new

实例化模型?使用#send是件坏事,还是我错过了关于send(association)方式的其他内容?

TL; DR:

我可以保存替换

f.object.class.reflect_on_association(association).klass.new

f.object.send(association).build

没有问题?

1 个答案:

答案 0 :(得分:4)

  

为什么Ryan Bates使用

     

f.object.class.reflect_on_association(association).klass.new

     

实例化模型?

因为集合的.accepts_nested_attributes对象在构建表单时不需要将集合元素链接到它。这将在稍后自动发生(如果您使用fields_for)。如果您需要该链接,我发现使用order.line_items.buildorder.send(:line_items).build时没有任何问题。

所以

  

我可以安全地替换

     

f.object.class.reflect_on_association(association).klass.new

     

     

f.object.send(association).build

     

没有问题?

是的,你可以。