Как 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] могут использоваться только с контроллеров.
У вас есть пара проблем здесь.
- У вас нет (или не должно быть) доступа к
params
переменная (она доступна только в контроллерах и представлениях, если вы не передаете ее в модель, что, вероятно, не то, что вы хотите). - Ваш
if
проверяет противproject.tasks
который является массивом - даже пустой массив оценивается какtrue
, так что ваша другая ветвь кода никогда не возникнет, независимо от того, есть ли у проекта задачи или нет. - Вероятно, вам следует устанавливать сообщения об ошибках для представления из действия ProjectsController # destroy, а не в вашей модели.
Решения:
- + Изменить
Project.find(params[:id])
вself
- вы хотите проверить задачи для каждого экземпляра проекта. - Изменить чек в вашем
if
заявление отif self.tasks
вif self.tasks.any?
который возвращает значение, которое вы хотите (false
если массив пуст,true
иначе). - Переместите 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