Rails 这在 Rails 里也是默认的吗 (where 前没有 object)?

dailysunshine · 2015年09月21日 · 最后由 adamshen 回复于 2015年09月22日 · 1661 次阅读

Hi, 今天看到一段代码:

来源:https://www.digitalocean.com/community/tutorials/how-to-configure-devise-and-omniauth-for-your-rails-application

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
     :omniauthable, :omniauth_providers => [:digitalocean]

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

在 method from_omniauth 中,调用 where 时前面没有调用它的 object,正常写法应该是 User.where(...) 吧,这是 Rails 的一种默认方式吗?

正确的方式是不写。

好处是:1. 没必要多打几个字。2. 当你把 User 改成其他名字时,不必增加其他的负担。

这种写法和 rails 无关,调用 where 的是 self, 而这里 self 指向的是 User.

@楼主 正如,@jpman 所言,调用方法时,Ruby 会做两件事

  • 找到这个方法,这个过程称为方法查找

  • 执行这个方法,为了做到这点,Ruby 要用到一个称为 self 的东西。

User.from_omniauth :执行User的类方法from_omniauth,此时,Userfrom_omniauth的方法接收者,充当self的角色。

请参考 Ruby 元编程(第二版)2.4 调用方法时发生了什么?27 页开始

因为self.from_omniauth(auth)是类方法,self指的就是User,所以where方法是被User调用的。

class method 调自己的 instance method,不用委托

需要 登录 后方可回复, 如果你还没有账号请 注册新账号