Reputation: 25001
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
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