where和first_or_create如何工作?

时间:2015-07-20 09:09:11

标签: ruby-on-rails oauth

从这段代码我有一个SQL检查,如果在任何寄存器中找不到provider和uid属性,则创建一个新的。一切都很好。 但是当创建一个新的寄存器时,它会变为为provider和uid检查值。这是怎么回事?该代码不应仅使用电子邮件,密码和名称属性值创建用户实例吗? 什么是SQL插入提供程序和uid?

def self.from_omniauth(hash)
    where(provider: hash.provider, uid: hash.uid).first_or_create do |user|
      user.email = hash.info.email
      user.password = Devise.friendly_token[0,20]
      user.username = hash.info.name
end

日志

User Load (25.0ms)  SELECT  "users".* FROM "users" WHERE "users"."provider" = $1 AND "users"."uid" = $2  ORDER BY "users"."id" ASC LIMIT 1  [["provider", "facebook"], ["uid", "879615942106023"]]
   (10.0ms)  BEGIN
User Exists (12.2ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = 'vinibol12@yahoo.com.br' LIMIT 1
  SQL (12.7ms)  INSERT INTO "users" ("provider", "uid", "email", "encrypted_password", "username", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["provider", "facebook"], ["uid", "879615942106023"], ["email", "vinibol12@yahoo.com.br"], ["encrypted_password", "$2a$10$z3oK6H1P5Z0It7VliVw1hehF.Mn1kFlvZbru919lDR.IiHb94Ha/u"], ["username", "Vinicius Antonio Bolzani"], ["created_at", "2015-07-20 08:58:04.227271"], ["updated_at", "2015-07-20 08:58:04.227271"]]
   (2.4ms)  COMMIT

2 个答案:

答案 0 :(得分:1)

first_or_create以这种方式工作,它首先在数据库中搜索where子句中的属性。如果发现它不会创建新的,如果失败则会创建新的。现在,即使对于新用户,查询也不知道给定的uid和提供者是否存在,因此必须首先运行查询以确保。见http://apidock.com/rails/v3.2.1/ActiveRecord/Relation/first_or_create。 '如果失败则尝试首先加载记录然后创建。

答案 1 :(得分:1)

如果在数据库中找不到,则

first_or_create会创建新记录,并且在创建时会使用您用于搜索的这些参数,这就是您设置provideruid的原因。如果您尚未传递任何阻止,则只会在provideruid设置的情况下在数据库中获得新记录。