class Song < ActiveRecord::Base
# Uses an integer of seconds to hold the length of the song
def length=(minutes)
write_attribute(:length, minutes.to_i * 60)
end
def length
read_attribute(:length) / 60
end
end
这是rails api doc的简单示例。
是否可以覆盖模型的所有属性而不会覆盖每个属性?
答案 0 :(得分:0)
class Song < ActiveRecord::Base
self.columns_hash.keys.each do |name|
define_method :"#{name}=" do
# set
end
define_method :"#{name}" do
# get
end
# OR
class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
def #{name}=
# set
end
def #{name}
# get
end
METHOD
end
end
答案 1 :(得分:0)
我不确定这是一个好主意的用例。但是,所有rails模型都动态地为它们分配了属性(假设它不在类中)。答案部分在你的问题中。
您可以覆盖read_attribute()和write_attribute()方法。这会将您的转换应用于每个属性,无论它们是由访问者写入还是在控制器中批量填充。请注意不要改变像'id'属性这样的重要属性。
Ruby有一个快捷方式,可以在rails代码中使用,可以帮助您。它是%w关键字。 %w将根据括号内的符号创建一个单词数组。因为它是一个数组,你可以做这样有用的事情:
@excludes = %w(id, name)
def read_attribute name
value = super
if(not @excludes.member? name)
value = value.to_i * 60
end
value
end
def write_attribute name, value
if(not @excludes.member? name)
value = value.to_i / 60
end
super
end
这应该让你开始。有更多高级构造,如使用lambdas等。请记住,您应该编写一些彻底的单元测试,以确保您没有任何意外的后果。您可能必须在排除列表中包含更多属性名称。
编辑:(读|写)_attributes - &gt; (读|写)_attribute