我在Rails模型上有一个名为:strip_whitespaces
的before_save过滤器,就像这样
before_save :strip_whitespaces
strip_whitespaces
过滤器是一种私有方法,它按以下方式定义:
private
def strip_whitespaces
self.name = name.split.join(" ") if attribute_present?("name")
self.description = description.split.join(" ") if attribute_present?("description")
self.aliases = aliases.split.join(" ") if attribute_present?("aliases")
end
如何使用ruby的send方法使这个方法干掉?一旦我必须向此过滤器添加更多字段,这也会有所帮助。
我有这样的想法,但它不起作用
%W[name description aliases].each do |attr|
self.send(attr) = self.send(attr).split.join(" ") if attribute_present?(attr)
end
答案 0 :(得分:2)
我甚至会把它分成两个私有方法:
def strip_whitespaces
%w(name description aliases).each do |attribute|
strip_whitespace_from attribute
end
end
def strip_whitespace_from(attr)
send("#{attr}=", send(attr).split.join(" ")) if attribute_present?(attr)
end
请注意,您不需要执行self.send
- 暗示self
- 而且您也不需要执行send("#{attr}")
因为插值无效,您可以做send(attr)
。
答案 1 :(得分:0)
这个答案很好地描述了ruby对象的send
方法的setter语法 - How to set "programmatically"\"iteratively" each class object attribute to a value?
使用以下代码解决了这个特殊情况下的问题
def strip_whitespaces
[:name, :description, :aliases].each do |attr|
self.send( "#{attr}=", self.send("#{attr}").split.join(" ") ) if attribute_present?(attr)
end
end
此处,代码首先获取属性self.send("#{attr}")
的当前值,剥离空格,然后通过"#{attr}="
setter将其设置为属性。 attribute_present?(attr)
是ActiveRecord::Base
类的一个方法,如果该属性不存在,则返回false。