我有一个带有以下型号的rails应用程序:
class Product < ActiveRecord::Base
has_many :stores, through: :product_store
attr_accessible :name, :global_uuid
end
class ProductStore < ActiveRecord::Base
attr_accessible :deleted, :product_id, :store_id, :global_uuid
belongs_to :product
belongs_to :store
end
由于此模型适用于移动应用的REST API,因此我会在设备上远程创建对象,然后与此模型同步。发生这种情况时,我可能需要在为ProductStore
设置id
之前创建Product
。我知道我可以批量处理API请求并找到一些解决方法,但我已经决定在移动应用中创建一个global_uuid
属性并进行同步。
我想知道的是如何在我的控制器中创建此代码:
def create
@product_store = ProductStore.new(params[:product_store])
...
end
请注意,它将接收product_global_uuid
参数而不是product_id
参数,并正确填充模型。
我想我可以覆盖ProductStore#new
,但我不确定这样做是否有任何衍生物。
答案 0 :(得分:1)
覆盖.new
是一项危险的业务,您不想参与其中。我会选择:
class ProductStore < ActiveRecord::Base
attr_accessible :product_global_uuid
attr_accessor :product_global_uuid
belongs_to :product
before_validation :attach_product_using_global_uuid, on: :create
private
def attach_product_using_global_uuid
self.product = Product.find_by_global_uuid! @product_global_uuid
end
end
拥有仅在模型创建中使用的这些人工attr_accessors
有点混乱,并且您希望避免传入任何不是您正在创建的模型的直接属性的任何内容。但正如你所说,有各种各样的考虑需要平衡,而且这不是世界上最糟糕的事情。