表用户没有名为password的列:INSERT INTO“users”

时间:2013-03-04 05:22:07

标签: ruby-on-rails

通过rails教程,我对这个错误感到难过。

尝试运行验证唯一性测试时出现上述错误。插入用户夹具后,这些错误似乎突然出现。我不明白我做错了什么,因为我的用户模型肯定有:在attr_accessible行中定义的密码,即使它似乎说用户没有密码属性?无论如何,相关的代码行如下:

模型/用户:

attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :profile_name
validates :profile_name, presence: true, uniqueness: true

夹具/ users.yml里:

name:
first_name: "user1"
last_name: "user2"
email: "email.com"
profile_name: "user"
password: "pass"
password_confirmation: "pass"

user_test.rb:

user.profile_name = users(:name).profile_name

4 个答案:

答案 0 :(得分:2)

我假设您正在关注teamtreehouse的Treebook示例,视频中建议的夹具无法正常工作,因为数据库中没有名为password或password_confirmation的列,它们是设计用于创建encrypted_pa​​ssword的字段。

因此,为了使夹具正确,您必须填充encrypted_pa​​ssword字段,如下所示:

name:
 first_name: "Boat"
 last_name: "Love"
 profile_name: "Supahlovar"
 email: "love.boat@boats.org"
 encrypted_password = "$2a$10$8uCZ9wCTsFoqa0aIfpssne4qtchcpqhepdU5WylZwh4GBAkgFWEYe"

我认为你可以使用加密密码的任何值,但这是从数据库中检索加密密码时的样子。

答案 1 :(得分:2)

has_secure_password依赖于BCrypt,后者用于哈希密码。您应该可以访问固定装置内的BCrypt。您也可以使用ERB。使用此技术为已知密码创建密码哈希值。

homer:
  first_name: "Homer"
  ...
  password_digest: <%= BCrypt::Password.create('donuts', cost: 4) %>

不要手动将password_digest设置为灯具中的某个未知值,而是使用BCrypt为您选择的密码创建密码摘要。

现在,在您的测试中,您可以这样做:

test "homer logs in with correct password" do
  user = users(:homer)

  get '/login'
  assert_success :response

  post_via_redirect '/login', username: user.username, password: user.password

  assert_equal '/profile', path
  assert_not_nil session[:user_id]
  assert_equal user.id, session[:user_id]
end

cost影响加密速度,最快速度为4.这对快速测试很有用。

您收到错误,因为passwordpassword_confirmation是由has_secure_password添加的虚拟属性,并且未映射到数据库。 password_digest列存储密码和加密版本的密码(称为摘要或散列)。 Fixtures将属性映射到数据库列,因此如果您插入一个未映射到列的属性,您将收到类似于您发现的SQL错误。

答案 2 :(得分:0)

它没有说用户没有密码属性,它说数据库中的用户表没有密码列(这是正确的,它不应该。)

如果没有看到其他代码(或者知道用户表的结构,请将其添加到您的问题中),我猜您在模型中缺少has_secure_password行。

答案 3 :(得分:-1)

直到更新我才会说:

  1. 通过迁移
  2. 将密码列添加到数据库
  3. 然后运行rake db:migrate
  4. (另外,如果你甚至没有测试数据库,也许你应该首先运行rake db:test:prepare