什么是在Rails 4中创建自引用关联的最佳方法?

时间:2015-02-16 07:43:45

标签: ruby-on-rails-4 associations self-reference

在我的项目中,我正在处理名为Workflows的对象。每个工作流都可以有许多子流(它调用的工作流)。同时,每个工作流程(包括具有子流程的工作流程)也可以充当调用子流程的Superflow,并且可以具有许多将其称为子流程的Superflow。

我目前正在尝试通过名为FlowRelation的模型使用连接表来实现此目的。

我已经按照我可以找到的每个教程阅读并阅读了我能找到的每篇文章,但我仍然无法使其正常工作。

工作流程模型:

class Workflow < ActiveRecord::Base
 belongs_to :superflow, :class_name => 'Workflow'
 has_many :subflows, :class_name => 'Workflow', :foreign_key => 'subflow_id'
end 

FlowRelation模型:

class FlowRelation < ActiveRecord::Base
 belongs_to :workflow
 belongs_to :flow, :class_name => "Workflow"
end

在我的工作流程内编辑edit.html.erb(使用SimpleForm)

<%= simple_form_for @workflow, :html => { :class => 'form-horizontal', :multipart => true } do |f| %>
<%= f.input :workflow_id %>
<%= error_span(@workflow[:workflow_id]) %>

<%= f.association :subflows, :include_blank => t('.select_workflow') %>
<%= error_span(@workflow[:subflow_id]) %>  

<%= f.association :superflow, :include_blank => t('.select_workflow') %>
<%= error_span(@workflow[:superflow_id]) %>

我的工作流程控制器非常简单

def new
  @workflow = Workflow.new
end

def edit
  @workflow = Workflow.find(params[:id])
  @workflow.save    
end 

目前,当我尝试将新的子流程保存到现有或新的工作流程时,不会保存任何内容。数据库中没有显示任何内容,我看到没有错误。

我还有一个FlowRelationsController

class FlowRelationsController < ApplicationController

 before_action :set_flow_relation, only: [:show, :edit, :update, :destroy]

  def create
    @flow_relation = current_workflow.flow_relations.build(:flow_id => params[:flow_id])
if @flow_relation.save
  flash[:notice] = "Added flow."
  redirect_to root_url
else
  flash[:error] = "Unable to add flow."
  redirect_to root_url
end
end

如果我尝试使用

为工作流索引创建一个add sub_flow按钮
<%= link_to "Add Subflow", flow_relations_path(:flow_id => workflow), :method => :post %>

我的flow_relations表也是空的。我收到以下错误:

undefined local variable or method `current_workflow' for #   
<FlowRelationsController:0x007f70154921e0>

我知道它是一堆碎片,但是我已经完全卡住了,在这一块墙上撞了几天。有人看到我在这里失踪的东西吗?我一直在尝试实现类似于RailsCasts上描述的内容但没有成功:http://railscasts.com/episodes/163-self-referential-association?view=asciicast

请帮助!

由于

2 个答案:

答案 0 :(得分:0)

如果不深入研究你在这里做的任何其他自引用模型,你看到的错误就是控制器错误。它不知道'current_workflow'。我的猜测是,在回调之前的'set_flow_relation'中,您正在设置@current_workflow。如果没有看到其余的控制器代码,我无法确定。

修复后,请发布您遇到的任何后续问题。

答案 1 :(得分:0)

我误解了几件不同的事情。我以为我会回答我自己的问题,以帮助清楚任何可能在同一条船上的人。

我上面的第一个主要问题是在FlowRelationsController中。我正在使用一个名为current_workflow的对象,它不存在。发生这种情况的原因是我在网上找到了关于此主题的唯一视频:http://railscasts.com/episodes/163-self-referential-association。这是一个创建资源,但与我试图完成的完全不同。在我的情况下没有创建current_workflow对象,因为我是从索引而不是我的应用程序的工作流程详细信息部分开始的

现在,关于如何实现我的原始目标。以下是我最终的结果:

工作流程模型

has_many :flow_relations
has_many :subflows, :through => :flow_relations

FlowRelation模型

self.primary_key = :workflow_id

belongs_to :workflow
belongs_to :subflow, :class_name => 'Workflow'

用于创建和编辑工作流程的simpleForm内部。 (这是一个很容易理解的关键部分。 - 使用所有工作流对象的集合与子流建立关联。

  <%= f.association :subflows, collection: Workflow.all, prompt: "Select Subflows" %>
  <%= error_span(@workflow[:subflow_id]) %>

由于Rails 4,工作流程控制器大致保持相同的一个关键差异。 - 我必须将workflow_params更改为允许!我在Worfklow控制器和FlowRelations控制器上都这样做了。我不确定我是如何理解这应该如何配置以获得更好的安全性,但在这个特定的应用程序中,安全性不是一个问题,因为它在内部运行。

def new
  @workflow = Workflow.new
end

def edit
  @workflow = Workflow.find(params[:id])
  @workflow.save    
end 

def workflow_params
  #params.require(:workflow).permit(:workflow_id, :flow_relations, :re_workflow_id, :name, :description, :superflow_id, :client_id, :variable_id, :required_variable_id, :flow_file)
 params.require(:workflow).permit!
end

我删除了添加子流按钮,因为现在可以通过标准的创建或编辑操作来完成

它是一堆东西,但基本上,最终结果是我现在有一个Workflow对象,它可以包含mnay子流,所有这些子流都可以是许多工作流的成员,所有这些都在一个Workflow类和一个FlowRelations类中用于handeling加入。