【问题标题】:Validate presence of nested attributes验证嵌套属性的存在
【发布时间】:2010-06-30 17:56:38
【问题描述】:

如何使用嵌套属性验证模型是否具有至少一个关联模型?这一直让我发疯,因为我确信我错过了一些简单的东西。例如,我想要求 List 始终至少有一个 Task。

class List < ActiveRecord::Base
  has_many :tasks, :dependent => :destroy
  accepts_nested_attributes_for :tasks, :allow_destroy => true
end

class Task < ActiveRecord::Base
  belongs_to :list
end

我尝试了许多不同的选择。

1- 向列表添加验证:

def validate
  if self.tasks.length < 1
    self.errors[:base] << "A list must have at least one task."
  end
end

但这仍然允许您删除现有列表的所有任务,因为在删除任务时,列表的验证发生在任务被销毁之前。

2- 在 before_save 回调中检查是否有任何任务未标记为销毁

before_save :check_tasks

private
#look for any task which won't be deleted
def check_tasks
  for t in self.tasks
    return true if ! t.marked_for_destruction?
  end
  false  
end

由于某种原因,我无法让它删除任何迭代列表任务的任务。如果我在def validate而不是回调中进行此检查,情况也是如此

3- 要求存在任务validates_presence_of :tasks,但这样它就不会删除任何任务

【问题讨论】:

    标签: ruby-on-rails validation activerecord


    【解决方案1】:

    您可以在验证方法中同时检查这两个条件:

      validate :check_tasks
      def check_tasks
        if self.tasks.size < 1 || self.tasks.all?{|task| task.marked_for_destruction? }
          errors.add_to_base("A list must have at least one task.")
        end
      end
    

    【讨论】:

    • 我喜欢你的风格,我同意它应该可以工作(我在我的测试中尝试了一些非常相似的东西),但是任何时候你从模型中的列表对象迭代任务,没有任何任务将被删除。我用 2.3.8 和 3.0.0beta4 都试过了,但无济于事
    • 很奇怪,我用 Rails 2.3.8 测试过,它可以工作。一件事 - 记录已从数据库中删除,但未从 list.tasks 缓存集合中删除。所以它看起来好像任务没有被删除。如果您需要在更新后访问您的对象,您可以尝试list.tasks.reload。
    【解决方案2】:

    我最终扩展了杂志的保存方法来解决这个问题。它就像一个魅力。

    def save
      saved = false
      ActiveRecord::Base.transaction do
        saved = super
        if self.conditions.size < 1
          saved = false
          errors[:base] << "A rule must have at least one condition."
          raise ActiveRecord::Rollback
        end
      end
      saved
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多