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

Max*_*ams 5 ruby activerecord ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

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

干杯,最大

Rob*_*vis 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
Run Code Online (Sandbox Code Playgroud)

使用这样:

class MyModel < ActiveRecord::Base
    include AttributeStripping

    # ...
end
Run Code Online (Sandbox Code Playgroud)

更新(2013年10月9日):

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

module AttributeStripper

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

end
Run Code Online (Sandbox Code Playgroud)

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

class MyModel < ActiveRecord::Base
  before_validation AttributeStripper

  # ...
end
Run Code Online (Sandbox Code Playgroud)

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


Wuk*_*ank 1

我前段时间为此目的编写了一个插件。我已经有一段时间没有尝试过它了,而且它也没有经过测试——所以不能保证它仍然有效。好处是一个干净的模型:

class Story < ActiveRecord::Base
  strip_strings :title, :abstract, :text
end
Run Code Online (Sandbox Code Playgroud)