【问题标题】:ActiveRecord: make all text fields have strip called on them before saving, unless specified otherwiseActiveRecord:除非另有说明,否则在保存之前使所有文本字段都调用它们
【发布时间】:2011-06-27 11:29:24
【问题描述】:

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

我认为它会很有用,而不是像过去那样放入一堆 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

但我正在寻找更好的方法。

干杯,最大

【问题讨论】:

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


    【解决方案1】:

    这是一个方便的模块,您可以将其放入 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
    

    更新(2013 年 9 月 10 日):

    几年后重新审视这个答案,我看到了风向的变化。现在有一种更清洁的方法。像这样创建一个模块:

    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。

    【讨论】:

    • 要以此为基础,请参阅edgeguides.rubyonrails.org/…
    • 似乎不适用于Model#update。该属性确实被剥离,但实际上并没有进入数据库。我不知道为什么。调用Model#save 似乎工作正常。
    【解决方案2】:

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

    我以前是这样操作输入的。

    但现在,我实际看到并遵循的最佳建议是存储用户键入的任何内容。 然后在后端进行后期处理以进行剥离。 如果您确实需要在数据库模型表中创建额外的数据库字段(已去除)。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 非常感谢@Wukerplank,我已经合并了它,它似乎可以完成这项工作:) 我想从最小惊喜的角度来看,明确列出我想要剥离的文本字段会更好在模型中,而不是像最初那样列出我不想剥离的那些。顺便说一句,您插件页面上的安装链接不起作用:我认为您只需在开始时将“https”替换为“git”。那里还有一个puts,大概是为了调试?干杯!最大
      • 是的,我还认为显式声明字段会使模型更具可读性。感谢您的提示,我会清理它:)
      • 你在哪里添加了字符串剥离器?我把它放在 lib/modules 中,它没有加载
      • @chrishough 我很久没有更新这个插件了——它甚至没有一个 gemified 版本。看看github.com/rmm5t/strip_attributes,它似乎是最新的。
      猜你喜欢
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2019-11-23
      相关资源
      最近更新 更多