在使用多态嵌套资源时,我遇到了inherited_resources问题,其中一个父级是命名空间控制器。下面是一个抽象的例子:
# routes.rb
resources :tasks do
resources :comments
end
namespace :admin do
resources :projects do
resources :comments
end
end
# comments_controller.rb
class CommentsController < InheritedResources::Base
belongs_to :projects, :tasks, :polymorphic => true
end
当我访问/admin/projects/1/comments
时,我收到此错误:
ActionController::RoutingError at /admin/projects/1/comments
uninitialized constant Admin::CommentsController
现在,如果我将控制器定义为 Admin::CommentsController
,我需要将文件移动到 controllers/admin
下,这反过来会引发 url 错误/tasks/1/comments
有没有办法解决这个问题?
为什么不CommentsController
保留在原地,并在从它继承admin/comments_controller.rb?
中为管理员创建一个单独的控制器?
class Admin::CommentsController < CommentsController
before_filter :do_some_admin_verification_stuff
# since we're inheriting from CommentsController you'll be using
# CommentsController's actions by default - if you want
# you can override them here with admin-specific stuff
protected
def do_some_admin_verification_stuff
# here you can check that your logged in used is indeed an admin,
# otherwise you can redirect them somewhere safe.
end
end
Rails Guide 中提到了您问题的简短回答。
基本上,您必须告诉路由映射器要使用哪个控制器,因为默认值不存在:
#routes.rb
namespace :admin do
resources :projects do
resources :comments, controller: 'comments'
end
end
这将解决您的路由问题,这实际上可能与Inherited Resources
无关。
另一方面,在命名空间内的嵌套控制器的情况下,我也无法使用Inherited Resources
。 正因为如此,我离开了那颗宝石。
我创建了您可能感兴趣的内容:一个控制器关注点,它将以考虑命名空间的方式定义继承资源提供的所有有用的路由帮助程序。 它不够聪明,无法处理可选或多重父系,但它省去了我很多键入长方法名称的时间。
class Manage::UsersController < ApplicationController
include RouteHelpers
layout "manage"
before_action :authenticate_admin!
before_action :load_parent
before_action :load_resource, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
create_resource_helpers :manage, ::Account, ::User
def index
@users = parent.users
respond_with [:manage, parent, @users]
end
def show
respond_with resource_params
end
def new
@user = parent.users.build
respond_with resource_params
end
# etc...
end
然后在我的观点中:
td = link_to 'Show', resource_path(user)
td = link_to 'Edit', edit_resource_path(user)
td = link_to 'Destroy', resource_path(user), data: {:confirm => 'Are you sure?'}, :method => :delete
希望对您有所帮助!