0

我有一个:strip_whitespaces在这样的 Rails 模型上调用的 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
4

2 回答 2

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).

于 2013-01-04T10:39:55.677 回答
0

这个答案很好地描述send了 ruby​​ 对象方法的 setter 语法 -如何“以编程方式”\“迭代地”将每个类对象属性设置为一个值?

通过使用以下代码解决了这种特殊情况下的问题

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。

于 2013-01-04T10:44:44.050 回答