【问题标题】:Iterating through Rails relationships recursively to find specific parent class递归遍历 Rails 关系以找到特定的父类
【发布时间】:2012-06-03 22:27:37
【问题描述】:

我有属于项目、任务和子任务的讨论(多态)。任务属于项目,子任务属于任务。

我有用户通过名为“突触”的连接表连接到项目。 Synapse 模型具有 user_id、project_id 和称为 :leader 的布尔字段,如果用户具有领导(AKA 管理员)权限,则表示该字段。

要让用户结束(结束)讨论,他需要成为当前项目的领导者或需要成为该讨论的创建者。这是讨论控制器中的“完成”方法:

 33   def finish
 34     if current_user.leader? || current_user.discussions.include?(@discussion)
 35       @discussion.update_attribute(:finished, true)
 36       redirect_to polymorphic_path([@parent, Discussion])
 37       flash[:notice] = "Discussion '#{@discussion.name}' finished"
 38     else
 39       flash[:alert] = 'You must be an admin to do that'
 40     end
 41   end

由于用户模型本身没有leader属性,我需要找到当前用户和项目之间对应的突触(确实有leader布尔字段,显示用户是否可以关闭讨论)。这是我在 application_controller 中找到突触的方法:

  9   def find_synapse(user,project)  
 10     user.synapses.find_by_project_id(project)
 11   end

要找到突触,我需要找到项目。到目前为止,我可以找到 Discussion 的父级,它可以是 Project、Task 或 Subtask 模型。

在我看来,我需要遍历父级,而不是在父级属于 Project 类时停止(for 循环?)。这个怎么做?这是最好的方法吗?顺便说一句,我尝试使用 switch-case(当 @parent.class 是 Task 时,执行此操作,当 class 为 Project 时,执行此操作),但看起来很hackish,而且我没有设法让它工作。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    如果你在项目、任务、子任务上定义一个方法owning_product,这样

    class Project
      def owning_project
        self
      end
    end
    
    class Task
      def owning_project
        project
      end
    end
    
    class Subtask
      def owning_project
        task.owning_project
      end
    end
    

    然后您可以在讨论的父级上致电owning_project 并取回相关项目。在某种程度上,这与您的 case 语句几乎相同,但使用继承系统为您进行切换。

    【讨论】:

    • 谢谢。这是最好的做法吗?难道没有一个循环可以做到这一切吗?
    • 不要认为有任何内置的东西可以做到这一点。
    • 我知道......这个拥有产品的方法非常性感,我会用那个......只是认为有一些方法可以用 for 循环来做到这一点,以避免在每个模型。
    【解决方案2】:

    如果你想让 switch-case 工作,它实际上必须打开@parent

    case @parent
    when Task
      ...
    when Project
      ...
    when Subtask
      ...
    end
    

    【讨论】:

    • 谢谢。这不是有点骇人听闻吗?似乎还有更优雅更好的方法……
    猜你喜欢
    • 2021-11-10
    • 2018-01-30
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多