Simple problem with Resources Routes


#1

Ok, I’m quite near to grasp all the resources and related routing
affair…

There is, anyway, a problem that I’m not able to solve: I do not get the
picture, here.

I have Offers, and I have Categories… (offers are categorized)

Offers could be listed and shown alone, so you have: /offers/23 or
/offers
and even /offers.rss

The problem comes when I try to get the Offers related to some Category

The REST way is /categories/32/offers but it won’t work… I can’'t (or
I
don’t know
how) use offers_url … or many other url helper that worked without
nesting…

Here it is my current (not working) routes.rb

map.connect ‘’, :controller => ‘offers’

map.resources :offers
map.resources :offers, :new => { :new => :any, :preview => :post }

map.resources :categories do |categories|
categories.resources :offers
end


Claudio C.


#2

You need a name prefix if you’re specifying resources multiple times. A
suggestion for your situation:

map.connect ‘’, :controller => ‘offers’

map.resources :offers, :new => { :new => :any, :preview => :post },
:name_prefix => ‘all_’

map.resources :categories do |categories|
categories.resources :offers
end

This gives you all_offers_path and categories_offers_path along with the
URLs of “/offers” and “/categories/12/offers” and all related
variations.

Jason


#3

Claudio,

The problem is that the routes conflict. The way to get the routes
untangled is to use :name_prefix => ‘something_’ and
possibly :path_prefix => ‘/something/:some_id’. I wanted to
experiment with this to see what all is necessary, because I’ve been
facing this in my own application.

The trick, once I got my routes untangled, was to make sure the views
and the controller stays untangled too. If I were in your
application, I’d probably create a:

before_filter :find_category

and then

def find_category
@category = nil
@category = Category.find(params[:category_id]) if
params[:category_id]
end

Then, when you call all the orders_url and order_url(@order), etc. in
your controller and views, you’ll put a conditional there, to pass
@category if @category (like @category ? order_url(@category,
@order) : order_url(@order).

Does that make sense?

To summarize, you’ll want to create the nested resources
with :name_prefix, and you’ll want to know what kind of url you’ll be
calling.

If you find a cleaner way to keep your routes untangled in your views
and controllers, please let me know. I’m going to have this
everywhere in an app I’m working on.

David


#4

@Jason: your solution worked flawlessy :slight_smile: What I did missed, was that
the
“all_” would go prefixed to the helpers… silly me

@David, thank you for your considerations! I’ve indeed resolved all my
problems
with the before_filter in my offers_controller, just before your mail
arrived :slight_smile:
But I don’t understand why you’d need all those conditionals…
Once I have the “all_” prefix (that now I understand), all my helpers
worked
as in:

all_offers_url() -> /offers
offers_url(@category) -> /categories/23/offers
all_offer_url(@offer) -> /offers/44
formatted_all_offers_path(:rss)
all_new_offer_url
all_preview_new_offer_url()

They are a bit verbose, but they make definitely sense to me.

Am I missing something?


#5

It’s elegant. I like it. This has been something that I’ve been
wondering about for a while, but haven’t had time to implement. When
I found the answer the other day, I was dying to try it out, but got
called away. Thanks both of you.