3

我正在使用 Devise railscast 关注 Ryan 的Omniauth。代码的一部分是:

class User < ActiveRecord::Base   
  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.username = auth.info.nickname
    end
  end
end

我在用 where().first_or_create 挠头。这段代码究竟做了什么?

我的猜测是 where() 语句适用于类 User。但是 Rails 怎么知道它等价于User.where(:provider => "provider_id passed by auth", :uid => "uid passed by auth")?

我的猜测是它会产生一个集合,然后如果集合为空,则创建一个新实例user并分配新属性。否则选择第一个实例并重新分配属性。

我的猜测正确吗?

4

1 回答 1

9

让我们把它分成几部分。

auth.slice(:provider, :uid)

auth 是一个包含 :provider 和 :uid 键的哈希。调用 .slice 进行身份验证会返回一个新的哈希,其中只有这些作为键。IE

auth = { provider: 'foo', uid: 'bar', some_other_key: 'blah' }
new_hash = auth.slice(:provider, :uid) # { provider: 'foo', uid: 'bar' }

first_or_create

相当于find_or_create_by。您可以阅读文档并查看它搜索与传递给的选项匹配的任何记录where。如果没有找到记录,它会尝试使用这些选项作为属性创建记录。

通过的块

user.provider = auth.provider
user.uid = auth.uid
user.username = auth.info.nickname

实际上只需要最后一行。前两行是多余的,因为它在 where 选项中。

于 2013-02-22T04:07:33.537 回答