Re: Learning deep associations in models

Walter Davis
2011-05-24T12:45:40Z

On May 24, 2011, at 6:06 AM, Wael Nasreddine wrote:

> Hello,
>
> I''m a web developer comping from Zend Framework and I''m
trying to
> learn
> Rails the right way and avoid Bad Practice from the start.
>
> I have a few questions in my head that I''m unable to get answered
on
> my
> own, so I''m going to try and get it explained with an example.
>
> Let''s say I''m building a site for a restaurant and the
website have a
> Menu model (which is essentially categories, like Pizza, Burgers
> etc..),
> a Product model that belongs to the menu and an Ingredient model which
> belongs to Product, code:
>
> class Menu < ActiveRecord::Base
>  has_many :products
>
>  # … validations and other logic
> end
>
> class Product < ActiveRecord::Base
>  belongs_to :menu
>  has_many :ingredients
>
>  accepts_nested_attributes_for :ingredients
>
>  # … validations and other logic
> end
>
> class Ingredient < ActiveRecord::Base
>  belongs_to :product
>
>  validates :name, :presence => true, :unique => true
>
>  # … other validations and other logic.
> end
>
> So far so good, however now I''m stuck because I''m not
sure how to code
> what I have in mind without ending up with a spaghetti code. In the
> new
> product form, I would like the user to be able to add ingredients (
> accepts_nested_attributes_for already there so I should be good for
> having the fields in the form ) but when the form has been filled and
> submitted, I want to create an ingredient if and only if it does not
> already exists, if on the other hand, it does, in this case the
> association should happen on the one that already exists, for example:
>
> Let''s say that I already have :onion in the ingredients table, if
I
> added a new product that has onion, I should not have two rows for the
> :onion ingredient (should not happen since I added a validation), but
> instead the association should happen on the one that already exists..

This is a great place to look at find_or_create_by_[your attribute
here]. I might try

@ingredient = Ingredient.find_or_create_by_name params[:ingredient]
[:name]
@product.igredients << @ingredient

Not sure about the params part, but the rest should work.

Walter

>
> How can I accomplish that? Should I be using a before_create hook?
> What
> should I do in that hook? or should I create a custom create method?
>
> Thank you.
>
> Wael
>
> --
> Posted via http://www.ruby-forum.com/.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonrails-
> talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com
> .
> For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
> .