pgb
pgb

Reputation: 25001

Creating new object with relations without the related id

I have a rails app with the following models:

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

Since this model is for a REST API of a mobile app, I create the objets remotely, on the devices, and then sync with this model. As this happens, it may happen that I have to create a ProductStore before having an id set for Product. I know I could batch the API requests and find some workaround, but I've settled to have a global_uuid attribute that gets created in the mobile app and synced.

What I'd like to know is how can I make this code in my controller:

def create
  @product_store = ProductStore.new(params[:product_store])
  ...
end

be aware that it will be receiving a product_global_uuid parameter instead of a product_id parameter and have it properly populate the model.

I figure I can override ProductStore#new but I'm not sure if there's any ramification when doing that.

Upvotes: 0

Views: 54

Answers (1)

RobHeaton
RobHeaton

Reputation: 1390

Overriding .new is a dangerous business, you don't want to get involved in doing that. I would just go with:

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

Having these kinds of artificial attr_accessors that are only used in model creation is kind of messy, and you want to avoid passing in anything that isn't a direct attribute of the model you are creating where possible. But as you say there are various considerations to balance, and it's not the worst thing in the world.

Upvotes: 1

Related Questions