数据未进入sqlite数据库 - Ruby on Rails

7
我正在运行 "rails console",然后执行以下命令:
 User.create(name:"John", email:"test@email.com", password:"foo", password_confirmation:"foo")

我得到了这个:
   (0.1ms)  begin transaction
  User Exists (0.2ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('test@email.com') LIMIT 1
   (0.1ms)  rollback transaction
 => #<User id: nil, name: "John", email: "test@email.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$mY0/9RgjwOU46ZYcSC0TFOCMxrPiqWTEHWe1K27O/3Ya...">

当我使用SQLite数据库浏览器查看sqlite数据库文件时,什么也没有显示。
以下是我的用户模型:
class User < ActiveRecord::Base

    #these attributes can be modified by the users
    attr_accessible :name, :email, :password, :password_confirmation
    #ruby's way of calling a method below...
    has_secure_password

    #validation testing
    validates :name, presence: true, length: { maximum: 50 }
    #regular expression (there is an official one)
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    #and add it..
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
        uniqueness:  { case_sensitive: false }
    #validate password 
    validates :password, length: {minimum: 6}
    validates :password_confirmation, presence: true

end

为什么我的数据库没有输入数据?

我无论输入什么都会出现这个错误!

例如:

1.9.3p125 :005 > User.create(name:"Smith", email:"smith@email.com", password:"foo", password_confirmation:"foo")
   (0.1ms)  begin transaction
  User Exists (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('smith@email.com') LIMIT 1
   (0.0ms)  rollback transaction
 => #<User id: nil, name: "Smith", email: "smith@email.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$6nzyRJ0IplI6B4bSoQEtUOIcrbFVl1ix3EAKPGJZjZQf...">

我从未使用那个电子邮件地址注册过Smith用户,但我仍然收到“用户已存在”的提示!

编辑:

我明白了错误原因。密码长度限制为5,而我输入的是3位密码,所以当我输入以下内容时:

User.create(name:"Smith", email:"smith@email.com", password:"foobar", password_confirmation:"foobar")
   (0.1ms)  begin transaction
  User Exists (0.2ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('smith@email.com') LIMIT 1
Binary data inserted for `string` type on column `password_digest`
  SQL (1.7ms)  INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", Mon, 12 Mar 2012 00:16:42 UTC +00:00], ["email", "smith@email.com"], ["name", "Smith"], ["password_digest", "$2a$10$v/FqAuUPpbdIJ44jVHxbKOJt/uoBTJVkP4KIhzJHNcF8rWPFfKusi"], ["updated_at", Mon, 12 Mar 2012 00:16:42 UTC +00:00]]
   (266.9ms)  commit transaction
 => #<User id: 1, name: "Smith", email: "smith@email.com", created_at: "2012-03-12 00:16:42", updated_at: "2012-03-12 00:16:42", password_digest: "$2a$10$v/FqAuUPpbdIJ44jVHxbKOJt/uoBTJVkP4KIhzJHNcF8...">

我的程序可以运行,但我仍然遇到了一个奇怪的“用户已存在”错误……有什么想法吗?


1
看起来您已经有一个使用电子邮件test@email.com的用户,因此电子邮件的:uniqueness验证失败。 - pjumble
1
如果你执行以下代码:user = User.new(name:"Smith", email:"smith@email.com", password:"foo", password_confirmation:"foo") 然后执行 puts user.errors,你会得到什么输出? - pjumble
1
@Test测试一下,尝试输入一些无意义的内容:User.create(name:"fwjwof42848yt24", email:"fwjwof42848yt24@email.com", password:"foo", password_confirmation:"foo"),看看是否会出现相同的问题。 - Ben Lee
1
始终检查 user.errors - 它会告诉你出了什么问题。 - ocodo
8个回答

8
  1. user = User.new

  2. 设置user的字段

  3. user.save

  4. 查看user.errors


1
检查 user.errors 是最好的答案。有很多不同的事情可能会出错。 - pyrospade
最好的做法是编写一个 RSpec 测试。 - ocodo
不幸的是,这并不能帮助你理解出了什么问题,只是知道出了问题。如果你编写了一个测试,你肯定想让它抛出 user.errors 中的内容。 - pyrospade
抱歉,那是暗示。应该期望出现错误。(例如密码验证失败、长度错误等) - ocodo
显式优于隐式...哦等等...这不是Python。再次感谢您的出色回答! - pyrospade

8

我通过谷歌搜索到这里,并了解了问题所在。实际上,这是一个垃圾错误信息。即使数据库干净,它看起来也会出现。问题是:密码只有3个字符长,这将导致问题。

    validates :password, length: {minimum: 6}

因此,如果您尝试使用更长的密码(和确认密码),它应该可以工作。 (注:我正在使用MySQL服务器,而不是SQLite,但我相当确定错误是相同的)


1
这对我来说是解决方案。我之前一直出现错误,因为我的密码少了一个字符。很好地发现了这个问题,Arthur! - thomallen
我认为"@messages={:password=>["is too short (minimum is 6 characters)"]}"非常清晰明了。 - ocodo

2
事实上,“用户已存在”并不是问题的根本原因,真正的原因是密码太短。你可以在rails控制台上输入user.errors来查看错误信息。
请参考以下错误示例。
irb(main):013:0> user = User.new(name:"caiqinghua", email:"caiqinghua@126.com", password:"admin",password_confirmation:"admin")

=> #<User id: nil, name: "caiqinghua", email: "caiqinghua@126.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$1d5jtpdkpl9hJPr/8s/dku1Y34.Aft/cAP5h/wrTN2sL...">
irb(main):014:0> user.save
   (0.2ms)  begin transaction
  User Exists (0.3ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('caiqinghua@126.com') LIMIT 1
   (0.2ms)  rollback transaction
=> false
irb(main):015:0> User.all
  User Load (0.6ms)  SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation []>
irb(main):016:0> User.create(name:"caiqing", email:"caiqing@126.com", password:"admin",password_confirmation:"admin")
   (0.3ms)  begin transaction
  User Exists (0.3ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('caiqing@126.com') LIMIT 1
   (0.1ms)  rollback transaction
=> #<User id: nil, name: "caiqing", email: "caiqing@126.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$Ossfc7NsL6/MjYVEjT5rJe/y4AiqdNZI2tCkrN1h8rHx...">

**irb(main):017:0> user.errors**
=> #<ActiveModel::Errors:0xba7d34c0 @base=#<User id: nil, name: "caiqinghua", email: "caiqinghua@126.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$1d5jtpdkpl9hJPr/8s/dku1Y34.Aft/cAP5h/wrTN2sL...">, @messages={:password=>["is too short (minimum is 6 characters)"]}>
irb(main):018:0> 

如果我将密码从“admin”更改为“admin123”,并且没有出现任何问题。

irb(main):018:0> 
irb(main):019:0* user = User.new(name:"caiqinghua", email:"caiqinghua@126.com", password:"admin123",password_confirmation:"admin123")
=> #<User id: nil, name: "caiqinghua", email: "caiqinghua@126.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$dHb.jezaiomN.ZE0pazkOOHDdac/K386h7zsORF93HtQ...">
irb(main):020:0> user.save
   (33.7ms)  begin transaction
  User Exists (9.9ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('caiqinghua@126.com') LIMIT 1
Binary data inserted for `string` type on column `password_digest`
  SQL (108.8ms)  INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", Fri, 27 Sep 2013 15:25:27 UTC +00:00], ["email", "caiqinghua@126.com"], ["name", "caiqinghua"], ["password_digest", "$2a$10$dHb.jezaiomN.ZE0pazkOOHDdac/K386h7zsORF93HtQb7wtj73Ha"], ["updated_at", Fri, 27 Sep 2013 15:25:27 UTC +00:00]]
   (112.7ms)  commit transaction
=> true
irb(main):021:0> User.all
  User Load (0.6ms)  SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation [#<User id: 2, name: "caiqinghua", email: "caiqinghua@126.com", created_at: "2013-09-27 15:25:27", updated_at: "2013-09-27 15:25:27", password_digest: "$2a$10$dHb.jezaiomN.ZE0pazkOOHDdac/K386h7zsORF93HtQ...">]>
irb(main):022:0> 

1
您正在尝试在数据库中创建一个重复的行,其中存在唯一验证。请查看您的错误消息(“用户已存在”):
User Exists (0.2ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('test@email.com') LIMIT 1

看一下你模型中的这行代码:
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
    uniqueness:  { case_sensitive: false }

这是验证用户的电子邮件地址是否唯一。因此,您必须已经在数据库中拥有一行,其中包含“test@email.com”作为电子邮件地址。


1

我不是100%确定,但我认为

用户存在(0.4毫秒)SELECT 1 FROM“users”WHERE LOWER(“users”。“email”)= LOWER('USer@example.com')LIMIT 1

它仅检查唯一性,无论您的查询是否通过或失败。

如果您更仔细地观察结果,您会意识到成功的结果将以蓝色显示“用户已存在”,而当您尝试插入重复用户时,失败的结果将以红色(或紫色)显示“用户已存在”我的情况)。

Ryan


1
也许你正在寻找错误的数据库。这是一个Rails应用程序,请查看数据库中的balbla.development模式,因为关于您的问题没有其他方法,必须有一行具有相同的电子邮件值。

1
我也遇到了这个问题,因为我的密码不超过6位。所以我把它改成了更长的密码,然后就可以了。但是我不知道为什么会出现“用户已存在”的异常,或者是我的问题。顺便说一下,我没有打开SQLIte数据库浏览器。

1
这是密码。
如果您想检查错误,请执行以下操作:
user = User.new(name:"John", email:"test@email.com", password:"foo", 
password_confirmation:"foo")

user.save

user.errors

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接