JJD
JJD

Reputation: 51884

How to filter list action in Rails using named routes?

Given I have two models: company and location. A company has many locations.
I found Ryan Bates' Named Routes very interesting.
So I added resources for each of my model in routes.rb.

resources :companies
resources :locations

This enables me to generate links based on named routes like <%= link_to "Companies", companies_path %> which results in http://localhost:3000/companies.

Now I want to filter the list of locations based on the company they belong to. Before working with named routes I accomplished this by add a link like the following.

<%= link_to "Locations for this company", { :controller => 'locations', :action => 'list', :company_id => company.id } %>

Here I pass the company_id to the LocationsController which filters the location in its list action.

def list
  @locations = Location.order("locations.id ASC").where(:company_id => @company.try(:id))
end

Upvotes: 1

Views: 3411

Answers (2)

nessur
nessur

Reputation: 1143

One option:

  resources :companies do
    get :list, :controller => :locations
  end

will produce this route:

   company_list GET    /companies/:company_id/list(.:format) {:action=>"list", :controller=>"locations"}

And this provides you, then, with a company_list helper method.

This, however,

  resources :companies do
    get :list, :controller => :locations
    resources :locations
  end

Will also provide you with a company_locations helper that points,instead, to the index action on the LocationsController instead of the list.

 company_locations GET    /companies/:company_id/locations(.:format)          {:action=>"index", :controller=>"locations"}

The latter is more RESTful, but you're the developer, so you get decide which naming helps you more.

The downside is that most of the actions/helpers on your Locations controller are now dependent on having a :company_id or instantiated Company model attached to them.

EDIT

3rd option:

resources :companies do
  get :list, :controller => :locations
end
resources :locations

This seems best, since other than the 'company_list' route, you don't claim to have much need for locations being filtered by company.

Upvotes: 2

Yule
Yule

Reputation: 9774

Depending on what your location model needs to do, I would suggest using nested resources;

resources :companies do   
    resources :locations 
end

Then do a rake routes, which will give you all sorts of new, nicer routes like:

company/id/locations

Upvotes: 2

Related Questions