自定义设计字段不保存更新(适用于创建)Rails 5,Devise 4,Ruby 2.3

时间:2016-12-09 03:50:45

标签: ruby-on-rails devise ruby-on-rails-5

使用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;
&#13;
&#13;

以及更新测试

&#13;
&#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;
&#13;
&#13;

上述测试因此结果失败:

&#13;
&#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;
&#13;
&#13;

这是我的应用程序控制器

&#13;
&#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;
&#13;
&#13;

用户参数清理程序以及用于获取自定义字段以保存新用户的用户参数清理程序

&#13;
&#13;
class UserParameterSanitizer < Devise::ParameterSanitizer
  def initilaize(*)
    super
    permit(:sign_up, keys: [:preferred])
  end
end
  
&#13;
&#13;
&#13;

最后是我的用户模型

&#13;
&#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;
&#13;
&#13;

我对铁轨很新,可能会忽略一些简单的事情,但我已经被困在这几个小时了,而且我尝试过的任何东西似乎都没有用。

1 个答案:

答案 0 :(得分:0)

我现在已经开始工作..我摆脱了UserParameterSanitzer,并在我的应用程序控制器中做了所有事情

&#13;
&#13;
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;
&#13;
&#13;

我还添加了

fill_in "Current password", with: @user.password

在我的测试中,由于设计需要保存当前密码而无法保存。