Rails 4 - How to add an index route for a nested resource to list all items independent of the parent resource

I have a Bar nested resource that belongs to Foo . I can successfully list all Bar objects belonging to any given Foo . But I also want to be able to create a view with all Bar elements listed together from any Foo object to which they belong.

Model structure:

 # app/models/foo.rb class Foo < ActiveRecord has_many :bars end # app/models/bar.rb class Bar < ActiveRecord belongs_to :foo end 

Routing is defined as:

 # config/routes.rb resources :foos do resources :bars end 

I get the expected routes from this configuration:

  foo_bars GET /foos/:foo_id/bars(.:format) bars#index POST /foos/:foo_id/bars(.:format) bars#create new_foo_bar GET /foos/:foo_id/bars/new(.:format) bars#new edit_bar GET /bars/:id/edit(.:format) bars#edit bar GET /bars/:id(.:format) bars#show PATCH /bars/:id(.:format) bars#update PUT /bars/:id(.:format) bars#update DELETE /bars/:id(.:format) bars#destroy foos GET /foos(.:format) foos#index POST /foos(.:format) foos#create new_foo GET /foos/new(.:format) foos#new edit_foo GET /foos/:id/edit(.:format) foos#edit foo GET /foos/:id(.:format) foos#show PATCH /foos/:id(.:format) foos#update PUT /foos/:id(.:format) foos#update DELETE /foos/:id(.:format) foos#destroy 

I need to create a route for bars#index that has no scope in the context of Foo . In other words, I essentially want:

 bars GET /bars(.:format) bars#index 

I tried using a shallow option, like this:

 # config/routes.rb resources :foos, shallow: true do resources :bars end 

However, this does not support: the action of the index, in the documentation .

What is the best way to do this? There is a useful discussion here , using before_filter to determine the scope, but since 2009. Evaluate any specific configuration guide for both the controller and the config/routes.rb !

+6
source share
1 answer

If you want to keep the index method foo_bars and the separate bars route:

Create your own route in routes.rb :

 get 'bars' => 'bars#index', as: :bars 

Set up your index method in your bars controller as described in your link, or simply:

 def index if params[:foo_id] @bars = Foo.find(params[:foo_id]).bars else @bars = Bar.all end end 

Then create the bars browsing directory (if you don't have one) and index.html.erb .


If you do not want to use the foo_bars index foo_bars :

Create your own route in routes.rb :

 get 'bars' => 'bars#index', as: :bars 

Edit existing routes to exclude the nested index:

 resources :foos do resources :bars, except: :index end 

Then the bars controller could be as follows:

 def index @bars = Bar.all end 

Then create the bars browsing directory (if you don't have one) and index.html.erb .

+4
source

All Articles