方法在哪里'来自使用Omniauth-Facebook宝石的时候?

时间:2014-08-24 14:44:07

标签: ruby-on-rails omniauth omniauth-facebook

下面显示的代码通常用于将rubygems,Omniauth和Omniauth-Facebook集成到rails应用程序中。我需要逐行解释这段代码。

class User < ActiveRecord::Base
  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.oauth_token = auth.credentials.token
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save!
    end
  end
end

1 个答案:

答案 0 :(得分:1)

from_omniauth是一个类方法,因此其中没有显式接收器的任何方法(例如a.b都有一个显式接收器a)使用隐式接收器(self) - 对于类方法self指的是类本身。因此,在User类上调用where,并由ActiveRecord Query接口定义。因此,where()可以像User.where()一样轻松地编写,但它是惯用的,可以省去不需要的显式接收器(因为它可以更轻松地重构类名,等等)。 )。

where的参数是声明auth.slice(:provder, :uid)的结果。在这里,auth基本上是一个哈希。 (它实际上是一个hashie对象,它是一个具有附加功能的哈希。)所以auth.slice最终调用Hash#slice - 这将只返回一个只包含键的新Hash /传递给slice的值,只留下{ provider: "facebook", uid: "THE_UID_HERE" }。因此总体结果是User.where(provider: "facebook", uid: "THE_UID_HERE")

然后调用first_or_initialize来查找与这些属性匹配的User对象或初始化一个新对象(不保存)。

最后,在结果对象上调用tap,并设置块范围方法user,等于对象(并在块的末尾返回用户)。基本上,这取代了创建局部变量user。那么,实际上,它会在找到或初始化的User对象上设置块中的所有属性,然后save!是用户。