question about params for resource routes

I have a application that I am building with edge rails. I am using the map.resources in my routes.config and this is what I have

map.resources :categories do |categories|
categories.resources :businesses do |businesses|

  businesses.resources :ratings
end
categories.resources :criterias

end

This is the first application that I attempted this with, so if anything is wrong please point it out to me. My question is that when using ratings_url I have to supply @category, @business to get the url to be created. While this is fine, when I want to use business_url I have to use @category in the views like so,

<%= link_to ‘Show’, business_path(@category, @business) %>

but in my business controller it is like this,

redirect_to business_url(@business)

and I do not have to supply the @category. Is it because one uses a path while the other uses a url? I have tests that run on all of this and they all pass, so I know that the code is correct. Why does it work this way? Why do I not have to supply the @category for business_url but I do for rating_url?

Hi --

I have a application that I am building with edge rails. I am using the
map.resources in my routes.config and this is what I have

map.resources :categories do |categories|
   categories.resources :businesses do |businesses|
     businesses.resources :ratings
   end
   categories.resources :criterias
end

This is the first application that I attempted this with, so if anything is
wrong please point it out to me. My question is that when using ratings_url
I have to supply @category, @business to get the url to be created. While
this is fine, when I want to use business_url I have to use @category in the
views like so,

<%= link_to 'Show', business_path(@category, @business) %>

but in my business controller it is like this,

redirect_to business_url(@business)

and I do not have to supply the @category. Is it because one uses a path
while the other uses a url? I have tests that run on all of this and they
all pass, so I know that the code is correct. Why does it work this way?
Why do I not have to supply the @category for business_url but I do for
rating_url?

I have a couple of follow-up questions:

What does business_url(@business) look like? Also, what are the id's
of @category and @business in your tests? (I ask the second because I
remember having a case, which I can't quite reconstruct, where the
fact that two objects had the same id actually caused a URL to work by
coincidence.)

David

Hey David,

The url for business_url look like

categories/:category_id/businesses/:business_id

the url for rating_url looks like

categories/:category_id/businesses/:business_id/ratings/:rating_id

The id’s in the business test are

:id for @business

:category_id for @category

the id’s in the rating test are

:id for @rating

:category_id for @category

:business_id for @business

Everything works great and no errors are being thrown, I am just curious why business_url(@business) only requires the @category in the views and not the controller while the rating_url requires @category and @business params at all times, in both the views and controller.

Hi --

Hey David,

The url for business_url look like

categories/:category_id/businesses/:business_id

the url for rating_url looks like

categories/:category_id/businesses/:business_id/ratings/:rating_id
The id's in the business test are

:id for @business

:category_id for @category

the id's in the rating test are

:id for @rating

:category_id for @category

:business_id for @business

Sorry, I didn't put it clearly. I meant: what is the actual return
value of a call to business_url(@business), for some particular
@business, and what are the id numbers of the objects in your tests?
I may be asking it the wrong way.... I'm trying to see where the
:category_id value came from if you didn't pass @category to the
method.

David

Sorry, about that.

You actually led me to the answer by asking the right questions. What was happening was that business_url(@business) was actually producing /categories/:business_id/businesses, so the @
business.id
was being used for the category id in the url. This was not being caught by tests or controller because they where not being tested for(I thought I was testing for it). The test now accounts for this and it is all working great. Sometimes bugs simply need to be talked about I guess to find the simple answer :slight_smile:

Thanks David,

John

Hi --

Sorry, about that.

You actually led me to the answer by asking the right questions. What was
happening was that business_url(@business) was actually producing
/categories/:business_id/businesses, so the @business.id was being used for
the category id in the url. This was not being caught by tests or
controller because they where not being tested for(I thought I was testing
for it). The test now accounts for this and it is all working great.
Sometimes bugs simply need to be talked about I guess to find the simple
answer :slight_smile:

Cool. You did indeed find just what I was suspecting.

I've found it cumbersome to have to always supply the nesting
arguments, and I'm working on a plugin (so far just a vicious hack of
the Rails source :slight_smile: that will allow you to do:

   business_url(@business)

and have it infer:

   business_url(@business.category, @business)

and also:

   businesses_url(@business)

would expand to:

   businesses_url(@business.category)

rather than using @business's id in the :category_id slot. Still a
work in progress....

David

David,

it will be great when you get it done. The only thing that I see a problem with in the way it is done now is that you get problems like I just had where I was forgetting a call in my test and it still passed with business_url(@business), whereas from what I understood the singular call would produce the “show” page and instead it was redirecting to the “index” because the two params where not present.

Hi --

Hi --

Sorry, about that.

You actually led me to the answer by asking the right questions. What

was

happening was that business_url(@business) was actually producing
/categories/:business_id/businesses, so the @business.id was being used

for

the category id in the url. This was not being caught by tests or
controller because they where not being tested for(I thought I was

testing

for it). The test now accounts for this and it is all working great.
Sometimes bugs simply need to be talked about I guess to find the simple
answer :slight_smile:

Cool. You did indeed find just what I was suspecting.

I've found it cumbersome to have to always supply the nesting
arguments, and I'm working on a plugin (so far just a vicious hack of
the Rails source :slight_smile: that will allow you to do:

   business_url(@business)

and have it infer:

   business_url(@business.category, @business)

and also:

   businesses_url(@business)

would expand to:

   businesses_url(@business.category)

rather than using @business's id in the :category_id slot. Still a
work in progress....

David,

it will be great when you get it done. The only thing that I see a problem
with in the way it is done now is that you get problems like I just had
where I was forgetting a call in my test and it still passed with
business_url(@business), whereas from what I understood the singular call
would produce the "show" page and instead it was redirecting to the "index"
because the two params where not present.

My current vicious hack does some heuristics to determine whether the
call is singular or plural -- basically, checking for an :id segment
-- and proceeds on that basis. I'm still probing the source and
trying things out, though. It will probably be dependent on
conformity to pretty predictable conventions, on the part of the
programmer, so the inferences can be made.

David