0

假设我们有以下类

class Foo < ActiveRecord::Base
  attr_accessible :name, :bars, :bazs

  def bars=(bars)
    baz = []
    bars.each { |b| barz << Baz.new(bar:b, magic_number: 123) }
  end

  def bars
    bazs.map(&:bar)
  end
end

class Bar < ActiveRecord::Base
  attr_accesible :name
end

class Baz < ActiveRecord::Base
  attr_accesible :magic_number, :bar
  has_one :bar
end

这是声明初始化方法的“rails”方式,因此当从哈希创建 Foo 时,会初始化 bazs。例如

Foo.new(name:"foo", bars:[Bar.new(name:"b1"), Bar.new(name:"b2")])

你不能使用after_initialize,因为self[:bars]返回 nil。另一种选择是覆盖该initialize方法,但 Rails 文档不推荐它,我不能使用barz=,因为初始化barz返回后nil,我必须使用self[:barz]=. 另一种选择是声明一个类构造函数方法,该方法通过调用 setter 进行正确的初始化,但它似乎不是 Ruby 方式(Foo.from(name:"foo", bars:[Bar.new(name:"b1"), Bar.new(name:"b2")]))。

谢谢

4

1 回答 1

0

好的,我最后所做的就是将所有内容声明为 attr_accessible 并覆盖初始化方法

class Foo < ActiveRecord::Base
  attr_accessible :name, :bars, :bazs 

  def initialize(attributes = nil, options = {})
    super
    self.bars = attributes[:bars]
  end

  def bars=(bars)
    self.bazs = []
    self.bars.each { |b| self.bazs << Baz.new(bar:b, magic_number: 123) }
  end

  def bars
    self.bazs.map(&:bar)
  end

end

我不知道要注意的一件事是,每次我需要调用 getter/setter 时,都需要使用self.

于 2012-06-22T15:17:19.853 回答