I've run into my second gotcha with Rails now, solved by the same function: update_attributes!
. Both times it took me entirely too long to figure out.
I have a many-to-many assocation, whose proper model implementation is excellently described in the official guide. As expected, my join model :belongs_to
each of the models in the many-to-many relationship. We have 3 models, all related to each other; 2 of them are related through the third:
Or, in code:
## in the Receipt class...
:belongs_to :store
:belongs_to :customer
## in the Store class..
:has_many :receipts
:has_many :customers, :through => :receipts
## in the Customer class...
:has_many :receipts
:has_many :stores, :through => :receipts
This ends up being really handy, because we can easily do things with collections owned by either a store or a customer: @store.receipts.total_price.each do |r|...
Adapting this blog-building example from the Rails guides, led me to create a receipt while building on a store:@receipt = @store.receipts.build(params[:receipt])
Being new at the time I wrote this code, I figured an easy-enough way to also determine customer ownership of receipts was to extend the assignments:@receipt = @store.receipts.build(params[:receipt]) = @customer.receipts.build(params[:receipt])
Seems like it should work, but this throws undefined method `build=' errors. I promptly erased that last error-causing bit and headed back to the drawing board -- this time checking the server logs while executing a successful new/create operation. All of my attributes but customer_id were being passed.
Solution: change controller's create method to update the attributes (new portion in bold):@receipt = @store.receipts.build(params[:receipt])
@receipt.update_attributes!(:customer_id => current_user.id)
Just like that, we're passing all attributes and everything in the @customer.receipts
collection is working!
- Note this does assume the excellent RESTful authentication plugin is being used and the user is logged in. Not a problem, since I don't expose my create method to users who aren't logged in, but worth noting nonetheless.
No comments:
Post a Comment