NOOB question about DB relationship and using find!

if class A has_many class b. and class B has_many class C.

when doing a find on class A, will my model have class c information?

like…

class maincategory

class subcategory
maincategory_id

class bottom.
subcategory_id

also, is it possible to get a model from the bottom class, and find out
whats its main category is?

THANKS!

Lets make it a little less abstract.

Class Country
has_many :states

Class State
belongs_to :country
has_many :cities

Class City
belongs_to :state

You can grab an array of related cities from the Country by doing:
Country.find(id).state.cities

You can go backwards, too:
City.find(id).state.country

Keep in mind the proper pluralization according to has_many or
belongs_to. Did that answer your question?

You can grab an array of related cities from the Country by doing:
Country.find(id).state.cities

Slight mistake here. You need to identify the state because a country
has_many states. So the proper way would be:

Country.find(id).state[array_index_number].cities

You can only go from 1:1 or 1:M, never M:M. This is why you cannot do:

Country.find(id).states.cities

thank you taylor for the explanation!

ok, now that i tried it out, i got some more questions please.

to expand on this
“Country.find(id).state[array_index_number].cities”

how can i return all the city names in a view for a country?

basically i will need a hash where in each position is the state name
linked to an array of city names for that state?

is it possible to do the find in the cities table like

Cities.find(
:all,
:conditions => ‘city.state.country_id => ?’,params[:selectedCountry]
)

?

I’ve never tried a reverse join like you suggest. Here is the ‘vanilla’ way of doing it:

The find method calls a Class, so it will be singular like: City.find,
Country.find, etc.

@country = Country.find(id_number, :include => {:states => :cities}}

will create a massive nested object with all states and cities properly
organized. To see the hash add <%= debug(@country) %> to your view.
But remember you cannot use ActiveRecord class methods on arrays so you
will have to iterate like:

<% for state in @country.states %> #iterate through states one at a time
<% for city in state.cities %> #iterate through each city one at a
time
<%= city.name %> #show each city object’s name
<% end %>
<% end %>

If you only had one layer of 1:M you could simply collect the find
results into an array and then spit out a string, “Atlanta, Macon,
Savannah”:

city_names = State.find(id_number).cities.collect {|c| c.name }.join(",
")

ALL THIS CODE IS UNTESTED!

nice! thanks Taylor! works awesomely!
@country = Country.find(id_number, :include => {:states => :cities}}

Taylor S. wrote:

I’ve never tried a reverse join like you suggest. Here is the ‘vanilla’ way of doing it:

The find method calls a Class, so it will be singular like: City.find,
Country.find, etc.

@country = Country.find(id_number, :include => {:states => :cities}}

will create a massive nested object with all states and cities properly
organized. To see the hash add <%= debug(@country) %> to your view.
But remember you cannot use ActiveRecord class methods on arrays so you
will have to iterate like:

<% for state in @country.states %> #iterate through states one at a time
<% for city in state.cities %> #iterate through each city one at a
time
<%= city.name %> #show each city object’s name
<% end %>
<% end %>

If you only had one layer of 1:M you could simply collect the find
results into an array and then spit out a string, “Atlanta, Macon,
Savannah”:

city_names = State.find(id_number).cities.collect {|c| c.name }.join(",
")

ALL THIS CODE IS UNTESTED!