如何初始化'attr_accessor'属性值?

时间:2011-08-16 16:22:35

标签: ruby-on-rails ruby ruby-on-rails-3 attributes initialization

  

可能重复:
  attr_accessor default values

我正在使用Ruby on Rails 3.0.9,我想在我的类\ model中初始化一些继承自attr_accessor的{​​{1}}属性值。也就是说,

...在我的模块中我有:

ActiveRecord::Base

我想设置class User < ActiveRecord::Base attr_accessor :attribute_name1, :attribute_name2, :attribute_name3, ... end 所有true属性值我该怎么做?

P.S。:当然我想解决上述问题,接近“Ruby on Rails Way”。我知道attr_accessor回调,但是通过使用该方法,我应该重复每个after_initialize语句,我想在attribute_name<N>语句中将值设置为true(。 ..这是干 - 不要重复自己)。也许有更好的方法来实现这一目标。 当您说明这些属性时,是否可以“动态”设置after_initialize属性值?也就是说,我希望一次声明并设置attr_accessor属性!

4 个答案:

答案 0 :(得分:12)

你有没有尝试过:

class User < ActiveRecord::Base
  attr_accessor :attribute_name1,
                :attribute_name2,
                :attribute_name3,
                ...

  after_initialize :set_attr

  def set_attr
    @attribute_name1 = true
    ...
  end
end

答案 1 :(得分:6)

对于Rails 3.2或更早版本,您可以使用attr_accessor_with_default

class User < ActiveRecord::Base
  attr_accessor_with_default :attribute_name1, true
  attr_accessor_with_default :attribute_name2, true
  attr_accessor_with_default :attribute_name3, true
  ...
end

由于您的默认值是不可变类型(布尔值),因此此方法的这种形式在此处可以安全使用。但是如果默认值是一个可变对象(包括数组或字符串),请不要使用它,因为所有新模型对象都将共享完全相同的实例,这可能不是您想要的。

相反,attr_accessor_with_default将接受一个块,每次都可以返回一个新实例:

attr_accessor_with_default(:attribute_name) { FizzBuzz.new }

答案 2 :(得分:3)

我只想定义一个懒惰加载你感兴趣的值的getter,并使用attr_writer来定义setter。例如,

class Cat
  attr_writer :amount_of_feet
  def amount_of_feet; @amount_of_feet ||= 4; end # usually true
end

如果你的意思是,可以用一些元编程重写:

class Cat
  # The below method could be defined in Module directly
  def self.defaulted_attributes(attributes)
    attributes.each do |attr, default|
      attr_writer attr

      define_method(attr) do
        instance_variable_get("@#{attr}") ||
          instance_variable_set("@#{attr}", default)
      end
    end
  end

  defaulted_attributes :amount_of_feet => 4
end

calin = Cat.new
print "calin had #{calin.amount_of_feet} feet... "
calin.amount_of_feet -= 1
puts "but I cut one of them, he now has #{calin.amount_of_feet}"

这是有效的,因为通常,计算默认值不会产生任何副作用,导致订单无关紧要,在您首次尝试访问它之前,不需要计算该值。

(Câlin是我的猫;他表现不错,仍有四只脚)

答案 3 :(得分:2)

残酷的解决方案

class User < ActiveRecord::Base
  @@attr_accessible = [:attribute_name1, :attribute_name2, :attribute_name3]
  attr_accessor *@@attr_accessible
  after_initialize :set_them_all
  def set_them_all
    @@attr_accessible.each do |a|
      instance_variable_set "@#{a}", true
    end
  end
end

或更多概念:Ruby: attr_accessor generated methods - how to iterate them (in to_s - custom format)?