【问题标题】:how do i validate the presence of a field only if another field was edited in rails?仅当在 rails 中编辑了另一个字段时,我如何验证字段的存在?
【发布时间】:2011-01-06 09:54:55
【问题描述】:

我有一个表,其中有一列名为生命周期_id,另一列名为生命周期变化_原因。 lifeycle_id 通常由系统根据其他因素自动更改,但某些用户具有手动更改生命周期的能力。如果他们这样做,我想要求他们提供更改的原因,但我不想在其他时间要求该字段。有人对我如何执行这种类型的验证有建议吗?

谢谢 :)

-C

【问题讨论】:

    标签: ruby-on-rails validation


    【解决方案1】:

    我可以看到几种不同的方式。我认为最好将另一个字段添加到表中,称为lifecycle_id_original。然后您的模型将包含如下代码:

    class Member < ActiveRecord::Base
      belongs_to :lifecycle
    
      validates :lifecycle_change_reason, :if => :lifecycle_changed?
    
      before_save :reset_original_lifecycle
    
      protected
    
      def lifecycle_changed?
        self.life_cycle_id != self.lifecycle_id_original && !self.lifecycle_id_original.nil?
      end
    
      def reset_original_lifecycle
        self.lifecycle_id_original = self.lifecycle_id
      end
    end
    

    当对象(本例中的成员)被验证时,只有在原始和生命周期_id 不相同时才需要生命周期更改原因。原始值也允许使用 nil 值,因为这是新创建记录时的值。

    然后在保存的时候,设置“original”来匹配lifecycle_id,这样下一个更新周期就可以正常工作了。

    这不像我想要的那样干净。我的第一个想法是使用attr_accessor,这样副本就不会一直存储在数据库中,但这意味着每次加载记录时都要设置该值。我不知道 ActiveRecord 模型有任何 on_load 样式回调。

    【讨论】:

      【解决方案2】:

      这似乎是控制器的用途。我意识到人们希望将逻辑推送到模型中,这是有充分理由的,但在这里我们要务实:如果您的系统正在自动更改此值,并且您的系统中只有一个点可以手动更改它,它确实在我看来,不要引入所有复杂性来简单地强制控制器中存在一个原因,比如:

      if params[:object_name][:life_cycle_id] != @object.life_cycle_id && params[:object_name][:life_cycle_change_reason].blank?
         flash[:error] = "You must enter a reason for changing the life cycle."
         redirect_to :back and return false # or whatever
      end
      

      【讨论】:

      • 这个问题是你没有在表单中得到所有很好的验证错误处理。
      • 当然你也知道怎么做:@object.errors.add(:life_cycle_change_reason, "必须提供。") 很简单。
      猜你喜欢
      • 1970-01-01
      • 2016-01-11
      • 2021-09-14
      • 2012-02-09
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多