Messed-up habtm relationship

Hi,

I have a many-to-many relationship between dishes and ingredients

class Dish < ActiveRecord::Base
has_and_belongs_to_many :ingredients
end

class Ingredient < ActiveRecord::Base
has_and_belongs_to_many :dishes
end

I have a join table dishes_ingredients

now when i access my_dish.ingredients, i get a list of what looks like
Ingredient objects, but the but they don’t have the right attributes:

#<Ingredient:0x29d3544 @readonly=true, @attributes={“name”=>“Chicken”,
“ingredient_id”=>“36”, “dish_id”=>“1”, “id”=>“1”}>

The join table’s columns ‘dish_id’ and ‘ingredient_id’ show up, and the
id is the id of the row in the join table, not the one of the ingredient
(Chicken).

I noticed this because the following was false where it should have been
true:

my_dish.ingredients.include?(chicken)

Ingo

I think you may have confused what include? does.

The description (Ruby doc) is:

Returns true if any member of enum equals obj. Equality is tested using
==.

When testing your Ingredient objects for equality, unless you have
specifically overridden == in your model, what’s being compared to
‘Chicken’
is actually an object of type Ingredient.

Consider:

my_dish.ingredients.find{|ingredient| ingredient.name == ‘Chicken’}

I’m pretty sure there’s a better way to do this, but find is always
reliable.

Hope this helps.

Keynan P. wrote:

class Ingredient < ActiveRecord::Base


Posted via http://www.ruby-forum.com/.


View this message in context:
http://www.nabble.com/-Rails--messed-up-habtm-relationship-tf2627404.html#a7332184
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

I found what the problem was: I had accidentally given the
dishes_ingredients join table an ‘ID’ column, and this was messing
things up.

Thanks for all your help!

Ingo

Thanks, Ross!

Actually, in my example the variable ‘chicken’ is thought to contain a
‘Ingredient’ object. So I should have written:

my_dish = Dish.find(:first)
chicken = Ingredient.find_by_name(“Chicken”)
my_dish.ingredients.include?(chicken)

That should work, or? But it doesn’t!

Ingo

Steve R. wrote:

I think you may have confused what include? does.

The description (Ruby doc) is:

Returns true if any member of enum equals obj. Equality is tested using
==.

When testing your Ingredient objects for equality, unless you have
specifically overridden == in your model, what’s being compared to
‘Chicken’
is actually an object of type Ingredient.

Consider:

my_dish.ingredients.find{|ingredient| ingredient.name == ‘Chicken’}

I’m pretty sure there’s a better way to do this, but find is always
reliable.

Hope this helps.

Keynan P. wrote:

class Ingredient < ActiveRecord::Base


Posted via http://www.ruby-forum.com/.


View this message in context:
http://www.nabble.com/-Rails--messed-up-habtm-relationship-tf2627404.html#a7332184
Sent from the RubyOnRails Users mailing list archive at Nabble.com.