【问题标题】:Ruby on Rails 3 TutorialRuby on Rails 3 教程
【发布时间】:2026-02-01 18:35:01
【问题描述】:

我正在阅读 Michael Hartl 的 http://ruby.railstutorial.org/ 教程。

我在第六章,特别是代码清单 6.27,如下所示:

    require 'spec_helper'

    describe User do

      before do
        @user = User.new(name: "Example User", email: "user@example.com", 
                         password: "foobar", password_confirmation: "foobar")
      end

      subject { @user }

      it { should respond_to(:name) }
      it { should respond_to(:email) }
      it { should respond_to(:password_digest) }
      it { should respond_to(:password) }
      it { should respond_to(:password_confirmation) }

      it { should be_valid }
    end

现在用户对象看起来像这样:

    class User < ActiveRecord::Base
      attr_accessible :email, :name, :password, :password_confirmation
      before_save { |user| user.email = email.downcase }

      validates :name, presence: true, length: {maximum: 50}
      VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
      validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniquenes  
      {case_sensitive: false}
    end

User 对象有六个属性:id、name、email、created_at、updated_at、password_digest。 password_digest 是存储散列密码的地方。但正如您所见,密码和密码确认字段不在数据库中。只有 password_digest 是。作者声称我们不需要将它们存储在数据库中,而只是在内存中临时创建它们。但是当我从 rspec 测试运行代码时:

    @user = User.new(name: "Example User", email: "user@example.com", 
                     password: "foobar", password_confirmation: "foobar")

我收到一条错误消息,告诉我密码和密码确认字段未定义。我该如何解决这个问题?

麦克

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    attr_accessible 只是告诉 Rails 允许在批量赋值中设置属性,如果属性不存在,它实际上不会创建这些属性。

    passwordpassword_confirmation需要使用attr_accessor,因为这些属性在数据库中没有对应的字段:

    class User < ActiveRecord::Base
      attr_accessor :password, :password_confirmation
      attr_accessible :email, :name, :password, :password_confirmation
      ...
    end
    

    【讨论】:

    • rails 的人需要做一些事情来给 attr_accessible 一个不同的名字。 .. 我见过很多人混淆 attr_accessor 和 attr_accessible
    • 好的,我发现了问题。我错过了 User 类中的 has_secure_password 行。我不知道这是为什么或如何工作的。有人可以请教我吗?
    • 可以查看has_secure_password here的源码和文档。这是一个基本功能,将一些额外功能混合到模型中(attr_reader :password 和一个 setter,当密码属性更改时自动生成加密密码/password_digest)。