Как Rails: если у проекта есть задачи, его не следует удалять: как я могу это исправить?

Привет, у меня есть проект, и у каждого проекта есть задачи. Задача принадлежит проекту. Прежде чем удалить проект, я хочу проверить, есть ли связанные задачи. Если есть задачи, я не хочу удалять проект. Если нет связанных задач, проект должен быть удален. Можете ли вы помочь мне с кодом? Что мне не хватает?

class Project < ActiveRecord::Base  
  before_destroy :check_tasks    

  def check_tasks 
    if Project.find(params[:id]).tasks  
      flash[:notice] = 'This project has tasks.'
      redirect_to :action => 'list_projects'    
    end 
  end
end

3 ответа

Верните false из метода before_destroy, чтобы предотвратить уничтожение экземпляра.

Метод также должен возвращать значимую ошибку для устранения неполадок.

class Project < ActiveRecord::Base
  before_destroy :check_tasks

  def check_tasks
    if self.tasks.any?
      errors.add_to_base "Project has tasks and cannot be destroyed."
      return false
    end
  end
end

Примечание: flash[:note] и params[:attr_name] могут использоваться только с контроллеров.

У вас есть пара проблем здесь.

  1. У вас нет (или не должно быть) доступа к params переменная (она доступна только в контроллерах и представлениях, если вы не передаете ее в модель, что, вероятно, не то, что вы хотите).
  2. Ваш if проверяет против project.tasks который является массивом - даже пустой массив оценивается как true, так что ваша другая ветвь кода никогда не возникнет, независимо от того, есть ли у проекта задачи или нет.
  3. Вероятно, вам следует устанавливать сообщения об ошибках для представления из действия ProjectsController # destroy, а не в вашей модели.

Решения:

  1. + Изменить Project.find(params[:id]) в self - вы хотите проверить задачи для каждого экземпляра проекта.
  2. Изменить чек в вашем if заявление от if self.tasks в if self.tasks.any? который возвращает значение, которое вы хотите (false если массив пуст, true иначе).
  3. Переместите flash[:note] из вашей модели в контроллер, а также вызов redirect_to, к которому они относятся. Это означает, что ваш check_tasks метод может быть изменен на следующее:

код:

def check_tasks
  return !self.tasks.any?
end

Должен ли чек быть само собой? (не уверен, откуда вы получаете параметры [:id]).

Хотя еще не проверил это - но так как мне нужно что-то подобное для моей модели Users, я посмотрю, как это работает, и вернусь к вам.

class Project < ActiveRecord::Base  
 before_destroy :check_tasks

 private

 def check_tasks
   #edited 
   if tasks.empty?  
     false
   end 
 end
Другие вопросы по тегам