Rails 请教一个 callback 中 self 的问题

qqren · 2018年06月26日 · 最后由 pinewong 回复于 2018年06月27日 · 1145 次阅读

class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }
end

这里调用 before_save 的时候,{ self.email = email.downcase } 这里的 self 为什么是实例,而不是类本身?记得 block 是没有新打开作用域的

如果 before_save 方法把接收到的块存下来了,最后调用时修改了当前环境(回调方法里,改成了实例环境),则调用时,self 的值就会和创建时不一样了。例子:

class C
  @block = nil

  def self.before_save(&block)
    @block = block
  end

  before_save { puts self }

  @block.call # => C
  new.instance_eval(&@block) # => <C:0x00007fa3c41810b8>
end

即 block 的当前环境 (self) 在调用的时候是可以改的。

pinewong 回复

这里 before_save 是类方法啊,为什么 new.instance_eval 一个实例方法可以调用的?

我上面没有在实例方法(new.instance_eval)里面调用类方法(before_save)啊,上面都是在 C 类环境里面操作。

当然要实现实例方法里调用类方法也是可以的,这是另一个问题。

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