我正在尝试在我正在构建的 Rails 3.2.13/Ruby 2.0.0p195 应用程序中使用我不熟悉的 Devise (2.2.4)。我打开 scoped_views 是因为我想拥有自己独立的用户和管理员视图。我创建了自己的 Users::RegistrationsController 似乎正在做我想做的事。我刚刚添加了自己的 Users::SessionsController,这是我遇到问题的地方。
作为第一步,我直接从 Devise::SessionsController 源中复制了几个操作方法,计划在它们工作后对其进行修改(我的控制器代码在这篇文章的底部)。但是我的“新”方法在调用时失败,并出现 NameError,因为“sign_in_params”显然是未定义的。
好吧,这看起来很奇怪,因为我继承自 Devise::SessionsController,当我查看 GitHub 上的源代码时,在底部的受保护部分中定义了 sign_in_params。所以我决定调查我的控制器是否正确地从 Devise::SessionsController 继承——而且看起来确实如此。我可以列出所有继承的方法,而不是缺少一个。所以我最终在 Rails 控制台中运行了以下代码:
(Devise::SessionsController.new.methods - DeviseController.new.methods).each {|m| puts m}
它产生以下输出:
_one_time_conditions_valid_68?
_one_time_conditions_valid_72?
_callback_before_75
_one_time_conditions_valid_76?
new
create
destroy
serialize_options
auth_options
如果我忽略带下划线的方法,剩下的就是 Devise::SessionsController 源中定义的所有方法,除了sign_in_params。我看不出我写的任何东西怎么会删除那个方法,我想不出还有什么可以尝试的。谷歌对这个问题保持沉默,所以我认为我在做一些非常愚蠢的事情,但我不知道是什么。请问有什么建议吗?其他人可能会尝试运行那段 Rails 控制台代码来看看他们得到了什么?
class Users::SessionsController < Devise::SessionsController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
prepend_before_filter :allow_params_authentication!, :only => :create
prepend_before_filter { request.env["devise.skip_timeout"] = true }
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
respond_with(resource, serialize_options(resource))
end
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
end
end