5

嗨,我有一个项目,每个项目都有任务。一个任务属于一个项目。在我删除项目之前,我想检查是否有相关任务。如果有任务我不想删除项目。如果没有关联的任务,则应删除该项目。你能帮我写代码吗?我错过了什么?

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
4

3 回答 3

6

从 before_destroy 方法返回false以防止实例被破坏。

该方法还应该返回一个有意义的错误以进行故障排除。

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[:notice] 和 params[:attr_name] 只能在控制器中使用。

于 2011-11-17T16:58:32.697 回答
2

你在这里有几个问题。

  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[:notice] 从模型移动到控制器,以及它们所属的 redirect_to 调用。这意味着您的check_tasks方法可以更改为以下内容:

代码:

def check_tasks
  return !self.tasks.any?
end
于 2011-11-17T17:40:58.637 回答
1

支票应该是self吗?(不知道你从哪里得到 params[:id])。

虽然还没有检查过 - 但由于我的用户模型需要类似的东西,我会看看它是如何工作的并回复你。

class Project < ActiveRecord::Base  
 before_destroy :check_tasks

 private

 def check_tasks
   #edited 
   if tasks.empty?  
     false
   end 
 end
于 2011-11-17T16:55:42.943 回答