我有一个Rails应用程序,有两个模型:SalesTransactions和PurchaseOrders。
在PurchaseOrders模型中,使用“purchase_order_number”作为关键字段注册新条目。我使用模型的create方法来搜索先前是否已经注册了“purchase_order_number”,如果是,则重用该记录并在SalesTransaction记录中使用其id。如果该名称尚未注册,我继续执行创建,然后在SalesTransaction中使用新的PurchaseOrder记录ID(链接到相关PO的foreign_id)。
请注意,在我在create方法中查找之前,我没有现有的PurchaseOrder记录ID(所以这不是'如何使用'accepts_nested_attributes_for'来更新记录?'的问题,一旦我有了id,我就能做到。
在某些情况下,我的应用程序会记录一个新的SalesTransaction,并同时创建一个新的PurchaseOrder。它使用accepts_nested_attributes_for来创建PurchaseOrder记录。
问题似乎是当使用'accepts_nested_attributes_for'时,不会调用create,因此我的模型没有机会拦截创建,并查找'purchase_order_number'是否已经注册并处理该情况
我很欣赏有关如何拦截'accepts_nested_attributes_for'创作以允许一些预处理的建议(即,如果具有该数字的PurchaseOrder记录已经存在,则查找,如果存在,请使用它。)
并非所有销售都有PurchaseOrder,因此PurchaseTransaction中的PurchaseOrder记录是可选的。
(我看过一个涉及:reject_if的kludge,但是这不允许我在父记录中添加现有记录id作为foreign_id。)
感谢。
答案 0 :(得分:1)
您可以使用validate
和save
回调来做您需要的事情。
假设设置:
class SalesTransaction < ActiveRecord::Base
belongs_to :purchase_order, :foreign_key => "po_purchase_order_no",
:primary_key => "purchase_order_no"
accepts_nested_attributes_for :purchase_order
end
class PurchaseOrder < ActiveRecord::Base
has_many :sales_transactions, :foreign_key => "po_purchase_order_no",
:primary_key => "purchase_order_no"
before_validation :check_for_exisitng_po # maybe only on create?
accepts_nested_attributes_for :sales_transactions
private
def check_for_exisitng_po
existing_po = PurchaseOrder.find_by_purchase_order_no(self.purchase_order_no)
if existing_po
self.id = existing_po.id
self.reload # don't like this, also will overwrite incoming attrs
@new_record = false # tell AR this is not a new record
end
true
end
end
这应该再次充分利用accepts_nested_attributes_for
。
gist w / tests
答案 1 :(得分:0)
两个想法:你看过协会回调了吗?也许你可以在这个级别“拦截”accepts_nested_attributes_for,使用:before_add在创建新记录之前检查它是否已经在数据库中。
另一个想法是进行后期处理。在after_save / update中,您可以使用名称(应该是唯一的)查找所有记录,如果有多个记录,则将它们合并。
答案 2 :(得分:0)
我打算写一个before_save函数,但你这样说:
它使用accepts_nested_attributes_for来创建PurchaseOrder记录。
那么在SalesTransaction
流程中,为什么要查找它?你应该让下一个可用......现在应该没有理由去搜索那些现在不存在的东西。
答案 3 :(得分:0)
我的结论是我没有错过一些技巧,在撰写本文时,没有一个简洁的解决方案,只有解决方法。
因此,我将重写我的应用程序以避免使用accept_nested_attributes_for,并单独发布SalesTransaction和PurchaseOrder记录,因此可以在两种情况下应用创建代码。
羞耻,因为accept_nested ......非常酷,但在这种情况下它还不够完整。
我仍然喜欢Rails; - )