我正在尝试向Devise的注册控制器添加一个自定义操作,允许用户更改其密码(我不能使用默认registrations#edit
,因为我需要一个只更改密码的表单,而不是电子邮件/用户名)。我在下面编写的实现在开发模式下工作,但是当我测试控制器时我得到了这个错误。
Failure/Error: get 'password'
ActionController::RoutingError:
No route matches {:controller=>"registrations", :action=>"password"}
有我的代码(我试图跳过不相关的部分)
spec/controllers/registrations_controller_spec.rb
describe RegistrationsController do
include Devise::TestHelpers
before :each do
request.env["devise.mapping"] = Devise.mappings[:users]
end
describe "GET 'password'" do
it "..." do
# The problem is here,
get 'password' # it raises ActionController::RoutingError
end
end
end
app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
# ...
def password
end
end
config/routes.rb
devise_for :users, path: 'account',
controllers: { registrations: 'registartions' },
skip: [:registartions, :sessions]
devise_scope :user do
# ...
scope '/account' do
get 'password' => 'devise/registartions#password', as: "change_password
do
end
spec_helper.rb
# ...
RSpec.configure do |config|
# ...
config.include Devise::TestHelpers, :type => :controller
end
答案 0 :(得分:1)
您是否使用以下内容设置了config / routes.rb。
devise_for :users do
get 'logout' => 'devise/sessions#destroy'
get 'changepassword' => 'devise/registrations#edit'
get 'access' => 'homepages#access'
get 'history' => 'policies#history'
get 'future' => 'policies#future'
end
devise_for :users, :controllers => { :sessions => :sessions }
resources :users
我有同样的问题。我设置路线然后它为我工作:)
答案 1 :(得分:1)
我通常会为此添加注释,但是我要包含一个代码块,并且在评论中会变得混乱。
您似乎试图在GET
上而不是在/password
上预先形成/account/password
。
从我正在阅读的内容中,您已获得/account/password
的映射:
devise_scope :user do # used to remove /users/ part from devise URLs
# ...
scope '/account' do # adds /account to URLs
get 'password' => 'devise/registartions#password', as: "change_password"
# this will match /account/passwordAnswer
do
end
因此,您应该删除范围,或者将测试中的get请求替换为:
get "/account/password", :user => @user
或者
get change_password_path(@user)
其中@user
是User
的模拟。
运行rake routes
进行确认。
答案 2 :(得分:0)
我不喜欢在我的规范中使用get "/account/password"
或路径。看似hacky。我在routes.rb文件中使用了更好的语法修复了类似的问题:
path: 'account'
devise_for
选项
controllers: {registrations: 'registrations'}
所以我的routes.rb看起来像这样:
devise_for :users,
path: 'account',
path_names: {sign_in: 'login', sign_out: 'logout', sign_up: 'register'},
controllers: {registrations: 'registrations'},
skip: [:passwords]
然后我可以在我的测试中使用get :new
。更干净。
希望这有助于其他人。
我正在使用设计3.0。