使用没有相关id的关系创建新对象

时间:2013-05-29 21:18:46

标签: ruby-on-rails uuid relation

我有一个带有以下型号的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,但我不确定这样做是否有任何衍生物。

1 个答案:

答案 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有点混乱,并且您希望避免传入任何不是您正在创建的模型的直接属性的任何内容。但正如你所说,有各种各样的考虑需要平衡,而且这不是世界上最糟糕的事情。