如何重新路由标准休息操作来设计控制器?

时间:2012-07-24 17:35:22

标签: ruby-on-rails-3 devise controller

我一直在构建一个小型Rails应用程序。这是一个非常标准的设置,但一个问题是需要为此项目更改默认的身份验证规则。非幂等注册操作必须全部仅限于经过身份验证的用户。

为此,我编写了一个自定义注册控制器并将其链接到路由中。所有自定义控制器真正需要做的是改变过滤要求。基于Rails控制器过滤documentation,我得到了最少的努力。

但它本身仅适用于特定于设计的操作,例如/ users / sign_up或/ users / edit。我还想将标准的Rails操作(/ users / new,/ users / 1 / edit等)连接到自定义控制器。我可以让动作实例化控制器 - 引导马可以说 - 但是当动作是新的而不是sign_up时,它会在过滤期间崩溃。

问题似乎是当action为'new'时,resource_name会产生nil,但是当它是'sign_up'时它就没问题了。我不明白为什么要设计关注或在代码中表示区别。我查看了其他问题,例如Update the User controller of deviseOverride devise registrations controller以及Custom Devise controller,但他们没有涉及此问题。

我得到的具体错误是

  

RegistrationsController中的NoMethodError#new

     

nil的未定义方法`name':NilClass

并且跟踪的顶部是

  

设计(2.1.2)app / controllers / devise_controller.rb:22:in   resource_name' app/controllers/registrations_controller.rb:104:in authenticate_scope!

第一次引用devise_mapping时显然正在发生这种情况。但是根据上面的stackoverflow问题,我还明确地为devise_mapping提供了帮助器,它们甚至都没有被调用。

任何人都可以解释或帮助我找出更进一步的目标吗?

来自routes.rb的

Fs::Application.routes.draw do
  devise_for :users, :controllers => { :registrations => 'registrations' } 
  resources :users, :except => [:index, :show], :controller => 'registrations'
  resources :users, :only => [:index, :show]

[...]

rake路线报告:

        new_user_session GET    /users/sign_in(.:format)            devise/sessions#new
            user_session POST   /users/sign_in(.:format)            devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)           devise/sessions#destroy
           user_password POST   /users/password(.:format)           devise/passwords#create
       new_user_password GET    /users/password/new(.:format)       devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format)      devise/passwords#edit
                         PUT    /users/password(.:format)           devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)             registrations#cancel
       user_registration POST   /users(.:format)                    registrations#create
   new_user_registration GET    /users/sign_up(.:format)            registrations#new
  edit_user_registration GET    /users/edit(.:format)               registrations#edit
                         PUT    /users(.:format)                    registrations#update
                         DELETE /users(.:format)                    registrations#destroy
                   users POST   /users(.:format)                    registrations#create
                new_user GET    /users/new(.:format)                registrations#new
               edit_user GET    /users/:id/edit(.:format)           registrations#edit
                    user PUT    /users/:id(.:format)                registrations#update
                         DELETE /users/:id(.:format)                registrations#destroy
                         GET    /users(.:format)                    users#index
                         GET    /users/:id(.:format)                users#show

我的registrations_controller.rb:

class RegistrationsController < Devise::RegistrationsController
  prepend_before_filter :authenticate_scope!, :except => [:index, :show]
  skip_filter :require_no_authentication
end

my users_helper.rb:

module UsersHelper
  # used by devise
  def resource_name
    :user 
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
end

使用:

Rails 3.2.6

Ruby 1.9.3

设计2.1.2

更新:粘贴在正确的跟踪输出中。

1 个答案:

答案 0 :(得分:3)

所以一个解决方案似乎是添加

  devise_scope :user do
    get '/users/new' => 'registrations#new'
  end

进入routes.rb。这可能不是最好的答案,但它确实有效。