Some table structure advice ?

Hi everyone,

I'm just starting a new project and it needs this type of structure:

an item has a brand and the brand has a number of models.

( e.g. The item might be an Advert for a Honda ( brand ), Civic ( model )

So in the admin maintenance I need to set up all the brands and models I need.

In the public area there needs to be a selection first for the brand then the model selection, which will only show the models for the selected brand.

In the advert table I could just have a belongs_to model ( as the model belongs_to :brand ).

But I'm not sure of the best approach.

Hope this makes sense.

Also can someone point me in the right direction to do the model drop down selection based on the previous selected brand ?

TIA - Dave Porter

Hi Dave . . .

an item has a brand and the brand has a number of models.

That sounds like this to me:

class Item < ActiveRecord::Base   has_many :brands end

class Brand < ActiveRecord::Base   belongs_to :item   has_many :models end

class Model < ActiveRecord::Base   belongs_to :brand end

I see the migrations looking like this (I've cut out a lot of boilerplate for brevity):

class CreateItems < ActiveRecord::Migration   // Nothing special needed end

class CreateBrands < ActiveRecord::Migration ...   t.column :name, :string   t.column :item_id, :int ... end

class CreateModels < ActiveRecord::Migration ...   t.column :name, :string   t.column :brand_id, :int ... end

Also can someone point me in the right direction to do the model drop down selection based on the previous selected brand ?

Sure. Take a look at the observe_field method we get with Rails + Prototype:

http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#M000535

Don't forget to put <% javascript_include_tag :defaults %> in your form rhtml if you're gonnna use observe_field. You basically want to observe the drop-down for the brand, probably with a :frequency => 0 so that it fires whenever a new brand is selected. In your controller you need an action that observe_field can call that returns the contents of the model drop-down (which will be the value for observe_field's :update param). Use the :with param to assign a name to the value that's chosen in your brand drop-down (something like :with => 'chosen_brand').

In your controller's action, you're going to do something along these lines:

@models = Brand.find(params[:chosen_brand]).models render :partial => 'populate_model_select'

This assumes that your brands drop-down has been populated from the DB, and the values of the options are the brand ID from the database (check out collection_select in ActionView::Helpers::FormOptionsHelper to accomplish that).

Then in your _populate_model_select.rhtml file, you'll have something like:

<% @models.each do |m| %>    <option value="<%= m.id %>"><%= m.name %></option> <% end %>

That oughtta get you started down the right path. :slight_smile:

Thanks Bill,

I'll work through that over the next few days and let youi know how I go.

regards, Dave