ruby-on-rails - Rails : How to validate password from input if there is not password field in database

标签 ruby-on-rails

我有包含字段的表: emailpassword_hashsalt

在用户注册时,我想验证密码和密码确认,但我总是收到错误,提示密码输入 can't be blank

这是我的模型:

attr_accessor :password

validates :password, :presence     => true,
                     :confirmation => true,
                     :length       => { :within => 6..40 }

我 guest 我无法验证不是数据库的字段,但是如何验证用户输入的密码?

我在数据库中没有密码字段,因为我将得到的 password 输入加密,然后将其存储在 db password_hash 字段中。

编辑:

这是数据库表:
class CreateStudents < ActiveRecord::Migration
  def change
    create_table :students do |t|
      t.string :first_name
      t.string :last_name
      t.string :email
      t.string :password_hash
      t.string :salt

      t.boolean :activated

      t.timestamps
    end
  end
end

这是注册 View :
<%= form_for @student, url: {action: 'create'} do |form| %>

  <p style="font-size:smaller; color:red">
  <% @student.errors.messages.each do |att, msg| %>
    <%= msg[0] %><br>
  <% end %>
  <p>
  <%= form.label :first_name %><br>
  <%= form.text_field :first_name %>
  <p>
  <%= form.label :last_name %><br>
  <%= form.text_field :last_name %>
  <p>
  <%= form.label :email %><br>
  <%= form.text_field :email %>
  <p>
  <%= form.label :password %><br>
  <%= form.password_field :password %>
  <p>
  <%= form.label :password_confirmation %><br>
  <%= form.password_field :password_confirmation %>
  <p>
  <%= form.submit %>

<% end %>

这是 Controller :
def sing_up
    @student = Student.new
    render 'sing_up'
end

def create
    @student = Student.new
    @student.first_name = params[:student][:first_name]
    @student.last_name = params[:student][:last_name]
    @student.email = params[:student][:email]

    @student.salt = BCrypt::Engine.generate_salt
    @student.password_hash = BCrypt::Engine.hash_secret(params[:student][:password], @student.salt)
    if @student.save
        redirect_to controller: 'singups', action: 'index'
    else
        render 'sing_up'
    end
end

最后,这是模型
class Student < ActiveRecord::Base
  attr_accessor :password
    validates :first_name, :length => { minimum: 3, message: "first_name" }
    validates :last_name, :length => { minimum: 3, message: "last_name" }
    validates :email, :presence => { message: 'email' },
              :format => { with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/ , message: 'email format' },
              :uniqueness => { message: 'uniqueness?' }
    validates :password, :confirmation => { message: 'password' },
                         :length => { minimum: 6, message: 'password length' }
end

每次用户输入密码时,第一次验证都会失败 :confirmation => { message: 'password' } ,无论密码是什么。

如果我删除 validates :password 部分,一切正常,但用户输入的密码未经过验证。

最佳答案

您正在验证用户的 password 属性,但您从未首先为其分配值。至少,您需要将此添加到您的 Controller 代码中:

@student.password = params[:student][:password]
@student.password_confirmation = params[:student][:password_confirmation]

然而,更简洁的方法是使用批量赋值——去掉所有的@student.xxx = yyy 并将其替换为:
@student = Studen.new(params[:student])

然后,将您的密码散列方法移动到模型中,如果存在密码属性,则在每次保存之前自动触发它:
class User < ActiveRecord::Base
  # ...
  before_save :hash_password, :if => proc{ |u| !u.password.blank? }
  # ....

  protected

  def hash_password
    self.salt = BCrypt::Engine.generate_salt
    self.password_hash = BCrypt::Engine.hash_secret(password, salt)
  end
end

这样你就不必在 Controller 中做任何事情,但是:
def create
  @student = Student.new(params[:student])
  if @student.save
    redirect_to controller: 'singups', action: 'index'
  else
    render 'sing_up'
  end
end

并在您的模型中拥有所有其他逻辑,它所属的位置。

编辑:为了使批量分配与最新版本的 Rails 3 一起使用,您需要将要分配的属性设置为 attr_accessible ,如下所示:
class Student < ActiveRecord::Base
  # ...
  attr_accessible :first_name, :last_name, :email, :password # but NOT the hash or salt!!

end

关于ruby-on-rails - Rails : How to validate password from input if there is not password field in database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10150800/

相关文章:

ruby-on-rails - 有没有办法在后续的 Rails 3 ActiveRecord 迁移中删除 id 列?

ruby-on-rails - 在rails中判断一个方法属于哪个类

ruby-on-rails - 使用 ActiveMerchant::Billing::EwayManagedGateway 时出现未初始化常量错误

ruby-on-rails - rails has_one 通过一个集合

sql - rails - 我不应该在 rails 迁移中使用默认值吗

ruby-on-rails - 有没有办法用 rspec 检查内部方法变量?

ruby-on-rails - form_for 第一个参数在 rails 4 中不能为 nil 或为空

ruby-on-rails - 在 Rails 中设置可选字段

ruby-on-rails - 如何使用 Rails 进行扩展

ruby-on-rails - 将电子邮件发送到多个逗号分隔的电子邮件地址