在Rails中创建一个深层嵌套的对象

时间:2011-11-13 21:27:59

标签: ruby-on-rails activerecord orm

我已经构建了一个小型API,当发布JSON对象时,会创建代表性的模型记录。数据如下所示:

{
  "customer": {
    "email": "michael@myemail.com",
    "first_name": "Michael T. Smith",
    "last_name": "",
    "shipping_address_1": "",
    "telephone": "5551211212",
    "source": "Purchase"
  },
  "order": {
    "system_order_id": "1070",
    "shipping_address_1": "",
    "billing_address_1": "123 Your Street",
    "shipping": "0",
    "tax": "0",
    "total": "299",
    "invoice_date": 1321157461,
    "status": "PROCESSING",
    "additional_specs": "This is my info!",
    "line_items": [
      {
        "quantity": "1",
        "price": "239",
        "product": "Thing A",
        "comments": "comments"
        "specification": {
          "width": "12",
          "length": "12",
        },
      },
      {
        "quantity": "1",
        "price": "239",
        "product": "Thing A",
        "comments": "comments"
        "specification": {
          "width": "12",
          "length": "12",
        },
      },
    ]
  }
}

问题是如何创建嵌套对象。我的模型设置如下:

class Order < ActiveRecord::Base
  has_many :line_items
  belongs_to :customer

  accepts_nested_attributes_for :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :order
  has_many :specifications
end

class Specification < ActiveRecord::Base
  belongs_to :LineItem 
end

我正在尝试使用以下代码创建记录:

@order = @customer.orders.build(@data[:order])
@order.save

有更好的方法吗?目前我收到此错误:ActiveRecord::AssociationTypeMismatch in ApiController#purchase_request LineItem(#70310607516240) expected, got Hash(#70310854628220)

谢谢!

2 个答案:

答案 0 :(得分:2)

accepts_nested_attributes_for为关联定义了一个新的setter方法:附加了_attributes的原始名称。

在您的情况下,line_items_attributes=模型上有Order方法,您需要使用该方法来利用嵌套属性功能。在构建模型之前交换密钥这样简单的事情可能会起作用,例如:

@data[:order][:line_items_attributes] = @data[:order].delete(:line_items)
@order = @customer.orders.build(@data[:order])
@order.save

答案 1 :(得分:1)

您可以这样使用accepts_nested_attributes_for: (在我的示例中,产品has_many的ProductionItineraries和ProductionItinereraries属于Products)

model / product.rb

has_many :production_itineraries, dependent: :delete_all
accepts_nested_attributes_for :production_itineraries, allow_destroy: true

model / production_itinerary.rb

belongs_to :product

要实例化:

products = Product.new
products.production_itineraries.build(other_production_itineraries_fields)

这样做,保存products后,将自动保存production_itinerary对象以及相应的product_id字段