Rails无密码的模型魔法更新属性
Rails Sorcery update attributes of model without password
我在 rails 4.1 应用程序中使用巫术进行用户身份验证。一切正常。但是当我尝试更新用户模型的特定属性(通过巫术验证)时,我得到一个错误,提示密码为空且太短。
这是来自控制台的片段
> user = User.last
=> # I get the user
> user.update(about_me: "I'm a user")
=> false
> user.update(about_me: "I'm a user", password: "secret")
=> true
这是我的模型代码
app/models/user.rb
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }
.....
end
我的控制器代码
app/controllers/users_controller.rb
class UsersController < ApplicationController
.....
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
flash[:notice] = "Profile successfully updated"
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:username, :name, :email, :password, :about_me)
end
end
还有我的更新表格
app/views/users/edit.html.erb
<%= form_for @user, method: :put do |f| %>
<% if @user.errors.any? %>
<div class="alert">
<p><%= pluralize(@user.errors.count, 'error') %></p>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :username, placeholder: 'Username' %>
<%= f.text_field :name, placeholder: 'Name' %>
<%= f.email_field :email, placeholder: 'Email' %>
<%= f.text_area :about_me, placeholder: 'About me' %>
<%= f.password_field :password, placeholder: 'Password' %>
<%= f.submit 'Save Changes', class: 'button' %>
<% end %>
如果我从表单中删除密码字段,我会收到有关密码为空和密码长度的错误消息。
这是与巫术有关还是我缺少 rails 本身?
有没有更好的方法来更新比方说只更新电子邮件字段而不影响其他任何内容?
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: :new_user?
private
def new_user?
new_record?
end
end
仅当它是 new_record 时才会检查验证,为此我们添加了自己的私有验证方法 new_user?。在正常 signups/registrations 期间,此函数将 return 为真。因此,在这些注册中,只需要验证密码。
在编辑期间,当然用户将是现有用户/new_record?将 return 错误。因此将跳过密码验证。
第二种方式:
class User < ActiveRecord::Base
attr_accessor :skip_password
validates :password, presence: true, length: { minimum: 6 }, unless: :skip_password
end
#users_controller.rb
def update
@user = User.find(params[:id])
@user.skip_password = true
if @user.update(user_params)
redirect_to @user
else
render 'edit'
end
end
这里我们添加了自己的自定义attr_accessorskip_password。如果 skip_password 值设置为 true,则在 edit/update 期间将跳过密码验证。
希望以上两种方式对您有所帮助:)
如果以后有人找这个话题,可以使用 changes
ActiveRecord 模型的映射:
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: -> {new_record? || changes[:crypted_password]}
.....
end
其中 :crypted_password
是 sorcery_config.crypted_password_attribute_name
的值。
Simple Password Authentication sorcery wiki 文章中目前也指出了这种验证条件。
我在 rails 4.1 应用程序中使用巫术进行用户身份验证。一切正常。但是当我尝试更新用户模型的特定属性(通过巫术验证)时,我得到一个错误,提示密码为空且太短。
这是来自控制台的片段
> user = User.last
=> # I get the user
> user.update(about_me: "I'm a user")
=> false
> user.update(about_me: "I'm a user", password: "secret")
=> true
这是我的模型代码
app/models/user.rb
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }
.....
end
我的控制器代码
app/controllers/users_controller.rb
class UsersController < ApplicationController
.....
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
flash[:notice] = "Profile successfully updated"
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:username, :name, :email, :password, :about_me)
end
end
还有我的更新表格
app/views/users/edit.html.erb
<%= form_for @user, method: :put do |f| %>
<% if @user.errors.any? %>
<div class="alert">
<p><%= pluralize(@user.errors.count, 'error') %></p>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :username, placeholder: 'Username' %>
<%= f.text_field :name, placeholder: 'Name' %>
<%= f.email_field :email, placeholder: 'Email' %>
<%= f.text_area :about_me, placeholder: 'About me' %>
<%= f.password_field :password, placeholder: 'Password' %>
<%= f.submit 'Save Changes', class: 'button' %>
<% end %>
如果我从表单中删除密码字段,我会收到有关密码为空和密码长度的错误消息。 这是与巫术有关还是我缺少 rails 本身? 有没有更好的方法来更新比方说只更新电子邮件字段而不影响其他任何内容?
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: :new_user?
private
def new_user?
new_record?
end
end
仅当它是 new_record 时才会检查验证,为此我们添加了自己的私有验证方法 new_user?。在正常 signups/registrations 期间,此函数将 return 为真。因此,在这些注册中,只需要验证密码。
在编辑期间,当然用户将是现有用户/new_record?将 return 错误。因此将跳过密码验证。
第二种方式:
class User < ActiveRecord::Base
attr_accessor :skip_password
validates :password, presence: true, length: { minimum: 6 }, unless: :skip_password
end
#users_controller.rb
def update
@user = User.find(params[:id])
@user.skip_password = true
if @user.update(user_params)
redirect_to @user
else
render 'edit'
end
end
这里我们添加了自己的自定义attr_accessorskip_password。如果 skip_password 值设置为 true,则在 edit/update 期间将跳过密码验证。
希望以上两种方式对您有所帮助:)
如果以后有人找这个话题,可以使用 changes
ActiveRecord 模型的映射:
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, presence: true, length: { minimum: 6 }, if: -> {new_record? || changes[:crypted_password]}
.....
end
其中 :crypted_password
是 sorcery_config.crypted_password_attribute_name
的值。
Simple Password Authentication sorcery wiki 文章中目前也指出了这种验证条件。