I've got a nested resource Bar
that belongs to Foo
. I can successfully list all Bar
objects that belong to any given Foo
. But I also want to be able to generate a view with all Bar
items listed together, from whatever Foo
object they belong to.
The model structure is:
# app/models/foo.rb
class Foo < ActiveRecord
has_many :bars
end
# app/models/bar.rb
class Bar < ActiveRecord
belongs_to :foo
end
The 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
What I need is to generate a route for bars#index
that isn't scoped within the context of foo
. In other words, I essentially want:
bars GET /bars(.:format) bars#index
I've tried using the shallow option, thus:
# config/routes.rb
resources :foos, shallow: true do
resources :bars
end
However, this doesn't support the :index action, per the documentation.
What's the best way to do this? There's a helpful Stack Overflow discussion here, using a before_filter
to determine scope -- but it's from 2009. Appreciate any specific guidance on how to set up both the controller and the config/routes.rb
file appropriately!
If you want to keep the scoped index method foo_bars
and a separate bars
route/view:
Create a custom 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 a bars
view directory (if you don't have one) and index.html.erb
.
If you don't want to keep the scoped index method foo_bars
:
Create a custom route in routes.rb
:
get 'bars' => 'bars#index', as: :bars
Edit your existing routes to exclude the nested index:
resources :foos do
resources :bars, except: :index
end
Then the bars
controller could just be:
def index
@bars = Bar.all
end
Then create a bars
view directory (if you don't have one) and index.html.erb
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With