Silly rails问题:类声明中的未定义方法

3 factory ruby-on-rails

我有一个用户类,我试图附加工厂创建的配置文件.这是班级:

class User < ActiveRecord::Base
  acts_as_authentic
  has_one :profile

  after_create {self.profile = ProfileFactory.create_profile(self.role)}

end
Run Code Online (Sandbox Code Playgroud)

工厂看起来像这样

class ProfileFactory
    def self.create_profile(role)
      String s = "#{role}#{"Profile"}"
      Object.const_get(s).new
    end
end
Run Code Online (Sandbox Code Playgroud)

由于某种原因,它不承认自己是一个用户.这是我在进行ProfileFactory.create_profile调用时遇到的错误

未定义的方法'角色' #<Class:0x2304218>

用户对象具有以下角色:在其迁移中声明的字符串.

任何帮助表示赞赏谢谢.

EmF*_*mFi 6

Duncan在使用你的工厂作为回调方面得到了正确的答案.但它可能会帮助您了解出了什么问题.

类方法接收类为self,实例方法接收实例为self.当您为块提供任何方法时,调用方法的范围将用于块.

after_create是一个类方法,它将回调添加回所提供的块或作为参数列出的方法.提供给回调的块(after_create,before_save等)在类方法的上下文中解释.因此,self不会引用正在创建的对象,而是引用正在创建的对象的Class.

在这个片段中:

  after_create {self.profile = ProfileFactory.create_profile(self.role)}
Run Code Online (Sandbox Code Playgroud)

self是User类,而不是您期望的User类的实例.

与Matt暗示的更传统的after_create语法相比,实例方法被添加到回调链中.在这种情况下,self指的是实例.

class User < ActiveRecord::Base
  has_one :profile
  after_create :add_profile

  protected

    def add_profile
      self.profile = ProfileFactory.create_profile(role)
    end
end
Run Code Online (Sandbox Code Playgroud)

EmFi,这很有道理.所以只是为了澄清一下,当从回调方法调用类中的方法但实际上不是在其中一个回调方法中时,允许我们解决这个类方法问题,并使用当前实例?

是的,但不是你想的原因.回调仅在传递符号时查找实例方法.

相反,你找到了解决实例方法问题的方法.你不能给回调一个类方法,但你可以为它提供一个调用它的块.我猜你也可以定义一个调用类方法的实例方法,但这看起来有些倒退.