【问题标题】:What is the best practices place to manipulate form data before saving in Rails 3?在 Rails 3 中保存之前操作表单数据的最佳实践是什么?
【发布时间】:2011-03-17 19:23:11
【问题描述】:

从 Rails 最佳实践的角度来看,在保存之前操作表单数据的最佳位置是什么?

例如,在联系表单上,我想确保所有数据都以大写形式保存(当人们在他们的“请联系我”表单提交中向你大喊大叫时,你不讨厌吗?:-))

  • 在控制器中进行操作是否更好?我可以在创建中执行此操作,也可以将其移动到某种私有方法中,这将在保存/更新之前将对象的所有字符串属性大写?

或者

  • 在模型 before_save 中做得更好吗? 对我来说应该在模型中完成它是有道理的,因为我可能希望所有记录都相同,无论我是在 rake 任务中还是通过 Web 界面对它们进行操作。

奖励:

如果我希望在我的所有模型上都使用它,并且能够根据具体情况覆盖默认值,我应该把它放在哪里?应用控制器? 在某些特殊情况下,您可能希望在不使用大写字母的情况下节省价值 - 即不大写的品牌产品(即 utorrent)或名称中应包含多个大写字母的姓氏(即爱尔兰和苏格兰名称,如麦当劳)

谢谢!

【问题讨论】:

    标签: ruby-on-rails design-patterns


    【解决方案1】:

    最简单的放置位置是在您的模型中。如果您觉得更合适,我建议使用 before_save 甚至 before_validation。像这样的东西可以解决问题:

    before_save :upcase_content
    
    def upcase_content
      self.content = self.content.upcase
    end
    

    此外,如果您希望逐个允许例外,您可以将 attr_accessor 添加到您的模型中。

    class MyModel < ActiveRecord::Base
    attr_accessor :dont_upcase
    
    before_save :upcase_content, :unless => :dont_upcase
    ...
    end
    

    然后当您创建模型时,将访问器设置为 true

    @model = Model.new(:brand_name => utorrent)
    @model.dont_upcase = true
    @model.save!
    

    【讨论】:

    • 关于访问器的想法很有趣——我需要进一步检查。
    • 是的,这是我通过railscast 了解到的——现在有点过时了,但它背后的理论保持不变
    【解决方案2】:

    把它放在你的模型中的最佳位置,这样你就有一个胖模型和一个瘦控制器,这是一件“好事”。

    如果您希望所有模型都可以使用此功能,我的建议是使用包含共享功能的模块,然后将其包含在您希望具有默认行为的所有模型中。

    【讨论】:

    • 我不会在每个模型中都包含它,我宁愿在我不需要的模型中覆盖它(我有超过 70 个模型,应该都有特定的字段以这种方式格式化,并且只有少数不应该有这种行为)我想我只会在 lib 中扩展活动记录。但感谢您的指点。
    • 另一种选择是拥有一个从任何地方继承的基类。我建议不要在初始化程序中打补丁。
    • 看看我自己的答案——这就是我最终做的。
    【解决方案3】:

    好的,根据其他回复的建议,我想出了这个解决方案:

    lib/clean_strings.rb

    module ActiveRecord
      class Base
        attr_accessor :dont_capitlize, :dont_strip
    
        before_save :_capitalize_strings, :unless => :dont_capitlize
        before_save :_strip_whitespaces,  :unless => :dont_strip
    
        def _capitalize_strings
          self.attributes.each_pair do |key, value|
            self[key] = value.capitalize if value.respond_to?('capitalize')
          end
        end
    
    
        def _strip_whitespaces
          self.attributes.each_pair do |key, value|
            self[key] = value.strip if value.respond_to?('strip')
          end
        end
    
      end
    end
    

    environment.rb中添加

    require "clean_strings"
    

    现在每当我这样做时

    @a.dont_capitalize = true
    @a.save!
    

    它会在根据我的规则保存之前对其进行清理(它会去除空格,但不会将其大写)。显然它需要更多的微调,但我认为这是为普通事物定义格式规则的好方法。这样我就不需要为额外的空格或不知道大写锁定在哪里的人清理每个表单输入!

    感谢大家的意见(全部赞成)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 2011-02-06
      • 2011-12-03
      相关资源
      最近更新 更多