ActiveRecord:除非另有说明,否则在保存之前,所有文本字段都会调用它们

时间:2011-06-27 11:29:25

标签: ruby-on-rails ruby activerecord trim strip

多年来,我遇到各种网站的各种问题,用户在字符串和文本字段的开头/结尾添加空格。有时这些会导致格式化/布局问题,有时它们会导致搜索问题(即搜索顺序看起来错误,即使它不是真的),有时它们实际上会使应用程序崩溃。

我认为这是有用的,而不是像过去那样放入一堆before_save回调,为ActiveRecord添加一些功能,以便在保存之前自动调用任何字符串/文本字段上的.strip,除非我告诉它不是,例如在类定义的顶部使用do_not_strip :field_x, :field_y或类似的东西。

在我去了解如何做到这一点之前,有没有人见过更好的解决方案?为了清楚起见,我已经知道我可以做到这一点:

before_save :strip_text_fields

def strip_text_fields
  self.field_x.strip!
  self.field_y.strip!
end

但我正在寻找一种更好的方式。

欢呼,最大

3 个答案:

答案 0 :(得分:10)

这是一个方便的模块,您可以将其放入lib并包含在模型中。它没有您提到的例外情况,但它会查找可能足够好的strip!方法。如果需要,您可以非常轻松地添加例外功能。

# lib/attribute_stripping.rb
module AttributeStripping

  def self.included(context)
    context.send :before_validation, :strip_whitespace_from_attributes
  end

  def strip_whitespace_from_attributes
    attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
  end

end

像这样使用:

class MyModel < ActiveRecord::Base
    include AttributeStripping

    # ...
end

更新(9/10/2013):

几年后重新回答这个问题,我看到风如何变化。现在有一个更清洁的方法。创建一个这样的模块:

module AttributeStripper

  def self.before_validation(model)
    model.attributes.each_value { |v| v.strip! if v.respond_to? :strip! }
    true
  end

end

并将其方法设置为在模型中的正确时间调用:

class MyModel < ActiveRecord::Base
  before_validation AttributeStripper

  # ...
end

这个模块更容易测试,因为它不是mixin。

答案 1 :(得分:2)

我在各种应用程序中处理过这类数据完整性问题。

我曾经像那样操纵输入。

但是现在,我实际看到和遵循的最好建议是存储用户输入的内容。 然后在后端进行后处理以完成剥离。 如果您确实需要数据库模型表,请创建其他数据库字段(解压缩)。

这个的主要原因是一个(主要的) - 当用户想要重新访问他们的数据,即编辑时,他们通常会期望看到他们输入的内容。次要原因是你将避免这样的可能性您的条带无法正常工作,并且会破坏数据或实际引发错误。

答案 2 :(得分:1)

前段时间我为此目的写了plugin。我有一段时间没试过它,它没有测试 - 所以没有保证它仍然有效。好处是一个干净的模型:

class Story < ActiveRecord::Base
  strip_strings :title, :abstract, :text
end