我尝试为我的用户模型创建一个名为edit_profile的新页面,以便用户可以编辑他的个人资料(字符串)。我跟随http://railscasts.com/episodes/41-conditional-validations
以下是表单(edit_profile.html.erb):
<%= form_for @user, :html => { :multipart => true } do |f| %>
<div class="field">
<%= f.label :profile %><br/>
<%= f.text_area :profile, :class => "round" %><br />
</div>
<div class="actions">
<%= submit_tag "update", :id => "updateSubmit" %>
</div>
<% end %>
我遇到的问题是我已经验证是否存在密码和密码确认。当我加载edit_profile视图时,即使在我尝试提交新配置文件之前,我仍会收到此消息Password is too short (minimum is 6 characters)
。
这是我的users_controller.rb:
def edit_profile
@user = current_user
@user.updating_password = false
@user.save
@title = "Edit profile"
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:success] = "Account updated."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
如果我只想在用户模型中修改个人资料属性,如何绕过密码验证?
谢谢!
其他相关信息:
user.rb
class User < ActiveRecord::Base
attr_accessor :password, :updating_password
attr_accessible :name, :email, :password, :password_confirmation, :photo,
:profile
before_save :downcase_fields
before_save :encrypt_password
validates_presence_of :password, :if => :should_validate_password?
validates_confirmation_of :password, :if => :should_validate_password?
def should_validate_password?
updating_password || new_record?
end
validates :name, :presence => true,
:name_format => true,
:uniqueness => { :case_sensitive => false }
validates :email, :presence => true,
:email_format => true,
:uniqueness => { :case_sensitive => false }
validates :password,
#:presence => true,
#:confirmation => true,
:length => { :within => 6..40 }
validates :profile, :length => { :maximum => 160 }
end
答案 0 :(得分:1)
(1)通常,当@user是新记录时,form_for将创建,当@user不是新记录时,它将进行更新。如果没有发生这种情况,那么你需要设置:url,也许是:方法。
<%= form_for @user, :url => (@user.new_record? ? users_path : user_path(@user),
:html => (@user.new_record? ? { :multipart => true, :method => :post } : { :multipart => true, :method => :put } do |f| %>
(2)你要求的是
class User
validate :validate_password_length
def validate_password_length
!new_record? || password.length >= 8
end
end
然而,允许新用户创建帐户,将密码更改为更短的密码。所以最好做到以下几点:
class User
validate :validate_password_length
def validate_password_length
!password_changed? || password.length >= 8
end
end
答案 1 :(得分:1)
鉴于您正在讨论配置文件编辑,即您已经拥有密码的注册用户,您可能希望有条件地跳过密码更新。
如果password
为空,只需删除password_confirmation
和password_confirmation
即可。即:
class UsersController < ApplicationController
before_filter :skip_password_attribute, only: :update
...
def update
...
end
private
def skip_password_attribute
if params[:password].blank? && params[:password_validation].blank?
params.except!(:password, :password_validation)
end
end
end
答案 2 :(得分:0)
我建议设计用户auth&amp;东西。这取自设计源(https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb):
validates_presence_of :password, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?
validates_length_of :password, :within => 6..128, :allow_blank => true
protected
def password_required?
!persisted? || !password.nil? || !password_confirmation.nil?
end
答案 3 :(得分:0)
以下是我最终解决这个问题的方法,虽然我很确定它并不理想 - 如果你有额外的密码强度规则,验证方法需要更复杂。
基本上,您根本不需要更改控制器 - 您可以修复模型来处理这种情况。
首先,您可以在password和password_confirmation字段中设置:on => :create
属性。但是,这会产生副作用,即用户必须在注册时提供合规密码,但之后可以将其更改为不合规密码。为解决此问题,我在执行更新时添加了before_update
回调以验证密码字段。我的User
课程现在看起来像这样:
class User < ActiveRecord::Base
...
before_update :check_password
...
validates :password, presence: true,
length: { minimum: 6 },
on: :create
validates :password_confirmation, presence: true,
on: :create
...
private
...
def check_password
is_ok = self.password.nil? || self.password.empty? || self.password.length >= 6
self.errors[:password] << "Password is too short (minimum is 6 characters)" unless is_ok
is_ok # The callback returns a Boolean value indicating success; if it fails, the save is blocked
end
end
如上面的评论中所述,此方法的结果确定是否将尝试保存。为了防止用户在没有错误消息的情况下被转储回编辑表单,我会注入一个。 [:password]
告诉它将错误附加到哪个字段。
答案 4 :(得分:-1)
您只需将:on => :create
添加到validate
。