views:

38

answers:

2

Hi!

I'd like to have a URL like this:

/payroll/region/1

and I'd like it to map to the Tasks Controller's payroll_list function. I'd also like to use REST. What's the best way to do this?

Many thanks!

+1  A: 

Well I'd suggest you better go with the convention how Rails handles this. If you still insist on using such "strange" URLs and want to ignore the problems/headaches this can create during further development, then try to use Refraction.

I don't want to be rude but currently it seems to me that you did not understand why restful URLs are the way they are. Please do understand the design behind this first, then rethink your application/controller and routing design. I bet you will be enlighted.

In this example, your URL should probably be /regions/1/payrolls with map.resources :regions, :has_many => :payrolls. Then your payroll list would be rendered by the PayrollsController having a params[:region_id] - and that actually makes sense (and probably what you tried to achieve with your URL layout). Code snippet:

def index
  if params[:region_id]
    @region = Region.find(params[:region_id])
    @payrolls = @region.payrolls
  else
    @payrolls = Payroll.all
  end
end

If you still want to have a resource under a different named URL, use the following:

map.resources :regions do |regions|
  regions.resources :tasks, :as => :payrolls
end

This will map the nested resources to the tasks controller using the named URL part "payrolls." But this probably does not work as you might expect because restful logic means you should handle the payroll model in the PayrollsController. Otherwise you might run into strange looking code. Maybe your design of the TasksController is just wrong? Rails will probably expect tasks to be handled over to your tasks controller although you name it payrolls. This can be confusing at least (however, it does not actually expect these being task models, so it will probably work).

BTW - Keep in mind: "restful" also means your application should answer to standard verbs on a resource, not just using "resourceful" routes. It's also about the GET, PUT, DELETE and POST http verbs, and of course the "edit", "new" etc default actions. Do not try to make your controllers big and complicated. Follow the motto "skinny controllers - fat models".

hurikhan77
@hurikhan77 - See? I knew somebody could help me out with this! :D That's just what I'm looking for. Thank you!
Mr M
P.S. - Yes, I need to re-read that documentation. There's a lot I need to re-read. Just need to finish this current project. (Thanks, again)
Mr M
Oh, wait... What do I do if I want the URL to have "payroll" in it, but have it use the tasks controller for the payroll requests?
Mr M
I've added more information to answer your question.
hurikhan77
A: 

OK, so a better question, then might be this:

How can I get it so that I use your suggestion:

/regions/1/payroll

and have that map RESTfully to:

Tasks controller with index, new, etc that are prefixed by "payroll_"?

Like this: TasksController#payroll_index or TasksController#payroll_new

Mr M
mapping to i.e. /regions/1/payroll/new etc
Mr M
This is not how it should be done... It's totally against the usual design decisions within Rails. Looks like you want some sort of encapsulation, so you might want to consider namespaces. Read about that.
hurikhan77