无法使用inherited_resources'多态belongs_to与命名空间控制器

时间:2013-12-18 09:23:50

标签: ruby-on-rails ruby ruby-on-rails-4 inherited-resources

当使用多态嵌套资源时,我遇到了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下移动该文件,这反过来会引发网址/tasks/1/comments的错误

我有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

为什么不将CommentsController保留在原来的位置,并为继承自admin/comments_controller.rb?的{​​{1}}管理员创建单独的控制器?

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

答案 1 :(得分:0)

Rails Guide中提到了对您的问题的简短回答。

基本上你必须告诉路由映射器使用哪个控制器,因为默认值不存在:

#routes.rb
namespace :admin do
  resources :projects do
    resources :comments, controller: 'comments'
  end
end

这将解决您的路由问题,这实际上可能与Inherited Resources无关。

另一方面,在命名空间内嵌套控制器的情况下,我也无法使用Inherited Resources。因为这个原因,我已经离开了那个宝石。

我创建了一些可能对您感兴趣的东西:controller concern,它将定义继承资源的所有有用路径助手,以一种占据命名空间的方式。它不够聪明,无法处理可选或多个父母,但是它为我节省了很多长方法名称。

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

希望有所帮助!