Ruby on rails 为现有子级创建具有多个:通过关系的新父记录

Ruby on rails 为现有子级创建具有多个:通过关系的新父记录,ruby-on-rails,activerecord,ruby-on-rails-4,rails-activerecord,Ruby On Rails,Activerecord,Ruby On Rails 4,Rails Activerecord,我正在开发RubyonRails API(版本4.0)来创建和更新发票。发票和产品之间的关系是一种有很多槽的关系:关系假设我有产品1、2和3。创建包含产品1和3的新发票时遇到问题。。当我运行下面的代码时,我得到了错误: Unknown primary key for table invoices_products in model InvoicesProduct. 这个错误对我来说没有意义,因为InvoicesProduct是一个联接表,不需要主键 设计中一个棘手的部分是,它需要跟踪哪个员工将

我正在开发RubyonRails API(版本4.0)来创建和更新发票。发票和产品之间的关系是一种
有很多槽的关系:
关系假设我有产品1、2和3。创建包含产品1和3的新发票时遇到问题。。当我运行下面的代码时,我得到了错误:

Unknown primary key for table invoices_products in model InvoicesProduct.
这个错误对我来说没有意义,因为InvoicesProduct是一个联接表,不需要主键

设计中一个棘手的部分是,它需要跟踪哪个员工将哪些产品添加到发票中,这就是为什么
invoices\u product
具有
employee\u id
。目前,这似乎不是问题的原因。以下是问题表格的DB设计:

发票控制器 这是我目前在控制器中的代码。错误消息出现在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
发票联
我可以通过向
invoices\u products
添加主键来修复关系。出于某种原因,我觉得联接表不需要
has\u many:through
关系的主键。但是,看看,示例联接表确实有一个主键。

这是因为您正在使用has\u many:through。如果您不想在联接表中使用id(或任何其他附加字段),请改用has\u many\u和\u own\u to

# /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
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"]
  }
}