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

时间:2009-10-21 02:50:47

标签: ruby-on-rails factory

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

class User < ActiveRecord::Base
  acts_as_authentic
  has_one :profile

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

end

,工厂看起来像这样

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

出于某种原因,它不会将自己视为用户。这是我在进行ProfileFactory.create_profile调用时遇到的错误

  

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

用户对象有一个角色:在迁移过程中声明的字符串。

感谢任何帮助。

3 个答案:

答案 0 :(得分:6)

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

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

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

在此片段中:

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

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
   EmFi,这很有道理。所以   只是为了澄清,在调用方法时   这是班上的   回调方法但实际上并非如此   其中一个回调方法,允许我们   绕过这个类方法   问题,并使用当前实例?

是的,但不是出于您的想法。回调仅在传递符号时查找实例方法。

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

答案 1 :(得分:1)

为什么不做一些更简单的事情?类似的东西:

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

  protected

    def add_profile
      self.create_profile(:role => self.role)
    end
end

class Profile < ActiveRecord::Base
  belongs_to :user

end

您是否来自Java背景?

答案 2 :(得分:1)

有问题的User对象作为参数传递给after_create块。

class User < ActiveRecord::Base
  after_create do |user|
    user.profile = ProfileFactory.create_profile(user.role)
    user.save
  end
end