ruby-on-rails-3resourcesfilterrailscastsnamed-routing

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

Solution

  • 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.