Ruby on rails 使用';发送';在保存前过滤器上

Ruby on rails 使用';发送';在保存前过滤器上,ruby-on-rails,ruby,activerecord,before-save,Ruby On Rails,Ruby,Activerecord,Before Save,在这样的Rails模型上,我有一个名为:strip\u whitespaces的before\u save过滤器 before_save :strip_whitespaces strip_whitespaces过滤器是一种私有方法,其定义如下: private def strip_whitespaces self.name = name.split.join(" ") if attribute_present?("name") self.description = d

在这样的Rails模型上,我有一个名为
:strip\u whitespaces
的before\u 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

我甚至想把它分成两个私有方法:

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)

这个答案很好地描述了ruby对象的
send
方法的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\u present?(attr)
ActiveRecord::Base
类上的一个方法,如果atribute不存在,则返回false。

谢谢!这个方法的一个变体有效-[:name,:description,:别名]。每个do | attr | self.send(“#{attr}=”,self.send(“#{attr}”).split.join(“”)end这很酷!。接受你的答案而不是我的,因为这是令人敬畏的。