Rails 4 - 如何为嵌套资源添加索引路由,以便列出独立于父资源的所有项目

Rails 4 - how do I add an index route for a nested resource, in order to list all items independent of parent resource

我有一个属于 Foo 的嵌套资源 Bar。我可以成功列出属于任何给定 Foo 的所有 Bar 个对象。但我也希望能够生成一个视图,其中列出了所有 Bar 项目,无论它们属于什么 Foo 对象。

模型结构为:

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

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

路由定义为:

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

我从这个配置中得到了预期的路线:

   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

我需要的是为 bars#index 生成一个不在 foo 范围内的路由。换句话说,我本质上想要:

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

我试过使用 shallow 选项,因此:

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

但是,根据 documentation.

,这不支持 :index 操作

最好的方法是什么?有一个有用的 Stack Overflow 讨论 here,使用 before_filter 来确定范围——但它是从 2009 年开始的。感谢任何关于如何正确设置控制器和 config/routes.rb 文件的具体指导!

如果你想保留作用域索引方法 foo_bars 和一个单独的 bars route/view:

routes.rb 中创建自定义路线:

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

按照 link 中所述在 bars 控制器中设置索引方法,或者简单地:

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

然后创建一个 bars 查看目录(如果你没有)和 index.html.erb.


如果你不想保留作用域索引方法foo_bars:

routes.rb 中创建自定义路线:

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

编辑现有路由以排除嵌套索引:

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

那么 bars 控制器可以是:

def index
  @bars = Bar.all
end

然后创建一个 bars 查看目录(如果你没有)和 index.html.erb.