Trying to pick a model setup without ridiculous routes

I am making a site with beer info. I want to have the beer name,
brewery and style info for every beer. So they all need to be
connected. But, I don't want two styles, i.e. "Pale Ale", "pale ale",
"paleale". So I was thinking of making style it's own model and people
could choose from a list, and then add one if it wasn't present
there.

But, if I had separate models for brewery also the URLs would be
nested like crazy. And, I want to be able to look up all the beers of
a certain style or from a certain brewery from the URL: example.com/
style/1, or example.com/brewery/1, as well as brew/1.

I know this is an involved question but I just can't wrap my mind
around it. I would appreciate any advice. Thanks for reading.

SHORT VERSION:

I want 3 models connected, but I don't want the nested URL craziness.
How?

Joel

Have a look at this article:
http://weblog.jamisbuck.org/2007/2/5/nesting-resources

Short version: it's better to limit nesting to one level.

Shallow nesting might also be helpful. See section 3.8.4:
http://guides.rubyonrails.org/routing.html#restful-routing-the-rails-default

Finally - a subject near and dear to my heart - beer!

One thing to remember about nested resources is its best to nest one
level at a time. Otherwise you get very complicated url's.

Depending on how you set the relations, you could have beer as a
nested resource of brewery and then set a separate nested resource
relationship between beer and style.

  map.resources :beers

  map.resources :breweries

  map.resources :styles

  map.resources :breweries, :has_many => [ :beers ]

  map.resources :beers, :has_many => [ :styles ]

So when you are dealing with breweries, you are only dealing with
beers. The same thing happens when you are working with beers, except
now you have the styles sub-resource.

Looking at this problem though it seems like a better solution would
be a has_and_belongs_to_many relationship between beers,breweries, and
styles. A brewery can make several different beers each of a different
style after all. To do this you would create a join table that only
includes key fields (beers_id, breweries_id, styles_id).

I found a tutorial that should point you in the right direction:
http://www.buildingwebapps.com/podcasts/79342-resources-page-links-categories-and-habtm/24793-show-notes

Thanks, I'll read up and come back. Looks like a good solution.

DISCLAIMER: fairly new to Rails myself, but not new to databases, nor
to software engineering (and coding concepts such as separation of
concerns), so this is sort of written from that POV. The Rails-ish
way may be different, but the following is what Makes Sense To Me.

You don't need to have them so closely coupled, nor to have the models
nested at all. The brewery, style, etc. could all be parameters of an
individual beer. Then you can slap a search on top of your index
function. So if you want to know what doppelbocks are made by the Foo
Manchoo Brew Krewe, you could do
index?style=doppelbock&brewery=Foo%20Manchoo%20Brew%20Krewe (or
whatever syntax you decide on for encoding multi-word things). And of
course to find all doppelbocks, or all from the FMBK, omit one or the
other of the parameters. And of course you could support other
parameters, like minrating= some number of stars, possibly separated
by rating authority, and so on.

-Dave

Could do all sorts of even more fun things with that too.

map.resources :styles, :has_many => [:beers]
map.resources :styles, :has_many => [:breweries]
map.resources :breweries, :has_many => [:styles]

Depending on how the user wants to go through (and the design of the
backend)...

Could do all sorts of even more fun things with that too.

map.resources :styles, :has_many => [:beers]
map.resources :styles, :has_many => [:breweries]
map.resources :breweries, :has_many => [:styles]

Depending on how the user wants to go through (and the design of the
backend)...

Could do all sorts of even more fun things with that too.

map.resources :styles, :has_many => [:beers]
map.resources :styles, :has_many => [:breweries]
map.resources :breweries, :has_many => [:styles]

Depending on how the user wants to go through (and the design of the
backend)...