How to deal with these 3 model's association?

Now I have 3 models, item category and sub-category
and 3 Tables in my database.

I planed to set the association like this.

Item
Belongs_to :category
Belongs_to :sub-category

category
Has_many :items
Has_many :sub_category

sub_category
belongs_to :category
Has_many :items

And now I want to have some dynamic drop down list in the items/new
page
When I chose one category, and the sub-category will dynamically
updated.
what other move do I need?

Is that right? It makes me feel confused with these associations.

Jette Chan wrote:

Now I have 3 models, item category and sub-category
and 3 Tables in my database.

I planed to set the association like this.

Item
Belongs_to :category
Belongs_to :sub-category

category
Has_many :items
Has_many :sub_category

sub_category
belongs_to :category
Has_many :items

And now I want to have some dynamic drop down list in the items/new
page
When I chose one category, and the sub-category will dynamically
updated.
what other move do I need?

Is that right? It makes me feel confused with these associations.

category.rb
has_many :sub_categories
has_many :items ,:through=>:sub_categories

sub_category.rb
belongs_to :category
has_many :items

item.rb
belongs_to :sub_category

by use of this association you can define get any of 2 by select of any
of 1 among three models

for that use Ajax Updater

A subcategory is always a child of a category. Lets set up your
associations
as such. It will use only one db column instead of two. Each item will
belong
to a subcategory; each subcategory will belong to a category. It will
look
something like this:

Category
/
Subcategories
/ |
Items Items Items

We will use ActiveRecord’s :through association. Your models will look
like
this:

Class Category
has_many :subcategories
has_many :items, :through => :subcategory

Class Subcategory
has_many :items

Class Item
belongs_to :subcategory

When you do this, Category will associate with an Item by tunneling
through
Subcategory. These helpful methods will now be available:

Item.category
Item.subcategory
Subcategory.category

Category.items
Category.subcategories
Subcategory.items

Now, we need to do your drop down list (called a “select” in Rails)
magic. I’m
not much of a Javascript buff, so this is a dirty little hack that
should
work. The idea is to have the “subcategory” select contained in a DIV.
The
contents on the DIV will originate from an action that only deals with
creating that select, likewise it will render a partial containing only
the
select’s markup. We’ll have an observer watch the “category” select, and
send
whatever it changes to to the “subcategory” select handler, which will
in
turn re-render the select with the appropriate contents. Your
controller,
model, view, and partial should look like this:

Item Controller:
def subcategory_handler
@subcategories = Category.find(params[:category_id]).subcategories
render :partial => “subcat_select”, :locals => {:s =>
@subcategories}
end

put this in the method “new”:

@category = Category.find :all
@subcategories = @category[0].subcategories

Item model:

add this virtual attribute, so that we don’t get NoMethod errors:

attr_accessor :category_id

Partial _subcat_select.html.erb
<%= select “item”, “subcategory_id”, s.collect {|s| [ s.name, s.id ]
} -%>

View for Item#new:
(I assume that the values in your select options are the category and
subcategory IDs.)
Category
<%= select “item”, “category_id”, @category.collect {|c| [ c.name,
c.id ] }, { }, { :id => “category” } -%>

Subcategory


<%= render :partial => “subcat_select”, :locals => {:s =>
@subcategories} -%>


(This must be called AFTER your select fields are defined!)
<%= observe_field :category, :url => { :action
=> :subcategory_handler }, :with => :category_id, :update
=> “subcategory_container” %>

That’s a pretty rough hack, but I tested it on Rails 2.1.0 and it works.
It’ll
take some fine tuning on your part. There might be a completely
different way
of handling such a thing, this is only one option to explore.

Hope it makes sense.