使用has_many创建新的父记录:通过现有子项的关系

时间:2014-06-18 19:12:38

标签: ruby-on-rails activerecord ruby-on-rails-4 rails-activerecord

我正在开发Ruby on Rails API(版本4.0)来创建和更新发票。发票和产品之间的关系是has_many trough:关系。 想象一下,我有产品1,2和& 3.我在创建包含产品1和产品的新发票时遇到问题。 3。即可。当我运行下面的代码时,我得到错误:

Unknown primary key for table invoices_products in model InvoicesProduct.

这个错误对我来说没有意义,因为InvoicesProduct是一个连接表,不需要主键。

有关设计的一个棘手的部分是,它需要跟踪哪个员工在发票中添加了哪些产品,这就是invoices_product employee_id的原因。目前似乎不是问题的原因。以下是问题中表格的数据库设计:

invoices has many products through invoices_product table

InvoicesController

这是我目前在控制器中的代码。错误消息出现在create的第一行:

def create
  invoice = Invoice.new(create_invoice_params)
  invoice.created_by = @current_user
  # eventually need to set employee_id on each invoice_product,
  # but just need to get it working first
  # invoice.invoices_products.map!{|link| link.employee = @current_user }
  invoice.save
  respond_with invoice
end

def create_invoice_params
  params.fetch(:invoice).permit(:customer_id, :status_code, :payment_method_code, product_ids: [])
end

发票

# /app/models/invoice.rb
class Invoice < ActiveRecord::Base
  validates_presence_of :customer
  validates_presence_of :created_by

  belongs_to :customer, inverse_of: :invoices
  belongs_to :created_by, inverse_of: :invoices, class_name: 'Employee'
  has_many :invoices_products, inverse_of: :invoice
  has_many :products, through: :invoices_products
end

InvoicesProduct

class InvoicesProduct < ActiveRecord::Base
  validates_presence_of :invoice
  validates_presence_of :product
  validates_presence_of :employee

  belongs_to :product, inverse_of: :invoices_products
  belongs_to :invoice, inverse_of: :invoices_products
  belongs_to :employee, inverse_of: :invoices_products
end

产品

# /app/models/product.rb
class Product < ActiveRecord::Base
  validates :name, presence: true, length: { maximum: 100 }

  has_many :invoices_products, inverse_of: :product
  has_many :invoices, through: :invoices_products
end

请求

这就是我对工作请求的想法,解决方案不需要匹配这个,但它是我一直在尝试的

{
  "invoice": {
    "customer_id": "1",
    "product_ids": ["1", "5", "8"]
  }
}

2 个答案:

答案 0 :(得分:1)

我能够通过向invoices_products添加主键来修复关系。出于某种原因,我认为连接表不需要has_many :through关系的主键。但是,查看example on the Rails guide site,示例连接表确实有一个主键。

答案 1 :(得分:0)

那是因为你使用的是has_many:through。如果您不想在联接表中使用id(或任何其他字段),请改用has_many_and_belongs_to