[英]Create new parent record with has_many :through relationship for existing children
I am working on a Ruby on Rails API (version 4.0) to create and update invoices. 我正在使用Ruby on Rails API(4.0版)来创建和更新发票。 The relationship between invoices and products is a
has_many trough:
relationship. 发票和产品之间的关系是
has_many trough:
关系。 Imagine I have product 1, 2, & 3. I am having trouble creating a new invoice that contains product 1 & 3. . 想象我有产品1、2和3。我在创建包含产品1和3的新发票时遇到了麻烦 。 When I run the code below I get the error:
当我运行下面的代码时,出现错误:
Unknown primary key for table invoices_products in model InvoicesProduct.
This error doesn't really make sense to me since InvoicesProduct is a join table and shouldn't require a primary key. 因为InvoicesProduct是一个联接表,并且不需要主键,所以这个错误对我来说真的没有意义。
One tricky part about the design is that it needs to track which employee added which products to the invoice, which is why invoices_product
has employee_id
. 关于设计的一个棘手的部分是,它需要跟踪哪个员工向发票中添加了哪些产品,这就是为什么
invoices_product
具有employee_id
。 It does not seem to be the cause of the problem at the moment. 目前看来,这并不是问题的原因。 Here is the DB design of the tables in questions:
这是有问题的表的数据库设计:
This is the code I currently have in the controller. 这是我目前在控制器中的代码。 The error message occurs on the first line of 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
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
This is what I've got in mind for a working request, the solution doesn't need to match this, but its what I've been trying 这是我对工作请求的考虑,解决方案不需要与此匹配,但是我一直在尝试
{
"invoice": {
"customer_id": "1",
"product_ids": ["1", "5", "8"]
}
}
I was able to fix the relationship by adding a primary key to the invoices_products
. 我可以通过在
invoices_products
添加主键来解决这种关系。 For some reason I was under the impression that join tables did not require a primary key for has_many :through
relationships. 由于某种原因,我给人的印象是联接表不需要
has_many :through
关系的主键。 However, looking at the example on the Rails guide site , the example join table does have a primary key. 但是,在Rails指南站点上查看示例 ,示例联接表确实具有主键。
That is because you are using has_many :through. 那是因为您正在使用has_many:through。 If you don't want id (or any other additional field) in the join table, use has_many_and_belongs_to instead
如果您不想在联接表中使用id(或其他任何其他字段),请使用has_many_and_belongs_to代替
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.