使用Rails 5,Ruby 2.3,Devise 4
您好,我一直在尝试构建一个具有首选用户和非首选用户的简单rails应用。我希望用户能够在更新帐户页面之间切换首选和非首选,并且似乎无法在提交时将更改保存到current_user。
首选是我的Users表中的布尔值,我的表单用于在新用户创建时将值设置为true。
以下是我的用户/ registrations / edit.html.erb
的副本
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :preferred, "Preferred" %><br />
<% if current_user.preferred? %>
<%= f.check_box :preferred, :checked => true, :value => true %>
<% elsif !current_user.preferred? %>
<%= f.check_box :preferred, :checked => false, :value => false %>
<% end %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<%= link_to "Back", :back %>
&#13;
以及更新测试
require "rails_helper"
RSpec.feature "Account Updated" do
# create a user that whose account will be updated
before do
@user = User.create(email: "johndoe@example.com", password: "password1@", password_confirmation: "password1@", preferred: "false")
end
scenario "A user opts into preferred" do
# visit root
visit "/"
# user signs in
click_link "Log in / Sign up"
expect(page.current_path).to eq(new_user_session_path)
fill_in "Email", with: @user.email
fill_in "Password", with: @user.password
click_button "Log in"
expect(page.current_path).to eq(root_path)
# user goes to account page
click_link("My Account")
expect(page.current_path).to eq(edit_user_registration_path)
# preferred checkbox should be unchecked
expect(page.has_unchecked_field?("Preferred"))
# user checks preferred status
check("Preferred")
# user saves changes
click_button "Update"
# expect user to be preferred
expect(@user.preferred).to eq(true)
# user recieves success message
expect(page).to have_content("You updated your account successfully.")
end
end
&#13;
上述测试因此结果失败:
1) Account Updated A user opts into preferred
Failure/Error: expect(@user.preferred).to eq(true)
expected: true
got: false
(compared using ==)
# ./spec/features/account_updates_spec.rb:29:in `block (2 levels) in <top (required)>'
Finished in 0.52815 seconds (files took 2.84 seconds to load)
&#13;
这是我的应用程序控制器
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
# allow custom sanitizer(s)
def devise_parameter_sanitizer
if resource_class == User
UserParameterSanitizer.new(User, :user, params)
else
super # use default
end
end
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:account_update, keys: [:preferred, :email, :password, :password_confirmation])
end
end
&#13;
用户参数清理程序以及用于获取自定义字段以保存新用户的用户参数清理程序
class UserParameterSanitizer < Devise::ParameterSanitizer
def initilaize(*)
super
permit(:sign_up, keys: [:preferred])
end
end
&#13;
最后是我的用户模型
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
&#13;
我对铁轨很新,可能会忽略一些简单的事情,但我已经被困在这几个小时了,而且我尝试过的任何东西似乎都没有用。
答案 0 :(得分:0)
我现在已经开始工作..我摆脱了UserParameterSanitzer,并在我的应用程序控制器中做了所有事情
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) do |user_params|
user_params.permit(:email, :password, :password_confirmation, :preferred)
end
devise_parameter_sanitizer.permit(:account_update) do |user_params|
user_params.permit(:email, :password, :password_confirmation, :preferred, :current_password)
end
end
end
&#13;
我还添加了
fill_in "Current password", with: @user.password
在我的测试中,由于设计需要保存当前密码而无法保存。