Kevin
Kevin

Reputation: 561

belongs_to has_many assosiation help

I created a joined table for the models category and products (both created with scaffold). The Product model is this:

class Product < ActiveRecord::Base
  belongs_to :category 

  def category_id
    category.id if category
  end

  def category_id=(id)
    self.category = Category.find_by_id(id) unless id.blank?
  end
end

and the category model is this:

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

In the form.html.erb I create a dropbox with all the classes for the user to choose from:

<p>
      <label for="product_category_id">Category:</label><br />
      <%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
</p>

Yet when I take a look at the show of the product:

<p>
  <b>Category:</b>
  <%= @product.category_id %>
</p>

or the list of the products (index.html.erb):

<td><%= product.category_id %></td>

There's no category. Just blank. I don't get it. Is something wrong with the category_id method or the association?

Upvotes: 1

Views: 627

Answers (2)

Shreyas
Shreyas

Reputation: 8757

Your association is obviously incorrect. As pointed out, the category has_many products. And in case you want to use a many-to-many relationship you're strongly advised to use the has_many :through relationship.

Upvotes: 0

Shadwell
Shadwell

Reputation: 34774

Firstly, you don't need the explicit category_id and category_id= methods. ActiveRecord will handle those for you for a belongs_to association.

Secondly, there seems to be a mismatch between whether you want a has_and_belongs_to_many or a has_many/belongs_to association. If you have a join table then you have the former, in which case both sides of the association should be declared with has_and_belongs_to_many. If you are just using a category_id on the products table then the other end of your association on Category should be has_many :products.

With a join model:

class Categorization < ActiveRecord::Base
  belongs_to :category
  belongs_to :product
end

you would define in your Product class:

has_many :categorizations
has_many :categories, :through => :categorizations

Then, because your association is a 'many' association, you do not get a .category method on a product. You do however get a categories method (plus several more methods - look at the has_many documentation). If you name your collection_select category_ids then it should work as expected. You may also want to add the 'multiple' option to the select in order to choose more than one category.

Upvotes: 1

Related Questions