Ruby on rails 确保模型属性始终被降级和剥离的最佳方法?

Ruby on rails 确保模型属性始终被降级和剥离的最佳方法?,ruby-on-rails,ruby,validation,Ruby On Rails,Ruby,Validation,我想知道确保用户提供的参数在所有情况下都被降级和剥离的最佳方法是什么 我希望实现以下目标: 确保属性不会保存到数据库中,除非已剥离/下框 对数据库的查询应始终关闭/剥离属性 验证针对用户提供的参数的降级/剥离版本运行 模型返回downcase/stripped属性(给定项#1,这应该不是问题) 您需要在保存之前编写一个回调方法,在该方法中,您可以对用户设置的属性进行降级和剥离 例如: class User < ActiveRecord::Base before_save :format

我想知道确保用户提供的参数在所有情况下都被降级和剥离的最佳方法是什么

我希望实现以下目标:

  • 确保属性不会保存到数据库中,除非已剥离/下框
  • 对数据库的查询应始终关闭/剥离属性
  • 验证针对用户提供的参数的降级/剥离版本运行
  • 模型返回downcase/stripped属性(给定项#1,这应该不是问题)

  • 您需要在保存之前编写一个
    回调方法,在该方法中,您可以对用户设置的属性进行降级和剥离

    例如:

    class User < ActiveRecord::Base
      before_save :format_values
    
      def format_values
        self.name = self.name.downcase
      end
    end
    
    class用户
    编辑


    我错过了你关于验证的第三点。因此,如果您还需要对这些值运行验证。您需要在\u验证之前使用
    回调。

    您可以在
    验证之前的回调中执行此操作:

    # in your model
    before_validation :normalize_attribute
    
    private
    def normalize_attribute
      # change `attribute` to your actual attribute's name
      self.attribute = attribute.strip.downcase if attribute
    end
    
    或者,您可以使用自定义设置器执行此操作:

    # change `attribute` to your actual attribute's name
    def attribute=(value)
      write_attribute(:attribute, value.strip.downcase) if value
    end
    
    第一个选项将在每次保存对象时清理属性的值,即使该值没有更改。如果在数据库中已经存在记录时引入此清理方法,这可能会有所帮助,因为这允许在Rails控制台中仅使用一行代码清理所有现有记录:
    Model.find_each(&:save)
    。第二个选项仅在设置值时对其进行清理。这是一个有点性能

    在这两种情况下,我建议检查
    if属性
    ,否则您可能会调用
    strip.downcase
    on
    nil
    值导致异常。

    类用户class User < ActiveRecord::Base
      before_validation :format_values
    
      def format_values
        self.name = self.name.strip.downcase if name
      end
    end
    
    验证前:格式化\u值 def格式\u值 self.name=self.name.strip.downcase if name 结束 结束
    根据评论更新了答案

    无需对回调进行想象(无论如何,不要使用回调)。只需覆盖属性的setter

    class MyModel
      def some_attribute=(value)
        value = value.strip.downcase if value
        write_attribute(:some_attribute, value)
      end
    end
    

    这难道不允许保留未降级/未剥离的值吗?如果您不介意,请在选择一个选项而不是另一个选项时更新您的答案以包括在内?@BillyBlobSnortin:Done