Проверить наличие вложенных атрибутов - PullRequest
4 голосов
/ 30 июня 2010

Как проверить, что модель имеет хотя бы одну связанную модель, используя вложенные атрибуты?Это сводит меня с ума, так как я уверен, что мне не хватает чего-то простого.Например, я хочу потребовать, чтобы в списке всегда была хотя бы одна задача.

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, но при этом он никогда не удалит никакие задачи

Ответы [ 2 ]

7 голосов
/ 03 июля 2010

Вы можете проверить оба условия вместе в методе проверки:

  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
3 голосов
/ 03 июля 2010

В итоге я расширил метод сохранения журнала, чтобы обойти проблему. Это сработало как шарм.

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
...