Rails 3:与多态关联有很多甚至很多关系

时间:2013-12-13 11:43:03

标签: ruby-on-rails ruby many-to-many has-many-through polymorphic-associations

我有2个模型,例如任务模型和task_relation模型 任务有许多父任务和子任务。

添加了以下关联 -

Task.rb

  has_many :from_tasks, :as => :relation, :class_name => "TaskRelation", 
                        :foreign_key => "task_from_id", :source => :parent, 
                        :conditions => {:relation_type => 'Parent'}, :dependent => :destroy
  has_many :to_tasks , :as => :relation, :class_name => "TaskRelation", 
                       :foreign_key => "task_to_id", :source => :child, 
                       :conditions => {:relation_type => 'Child'}, :dependent => :destroy
  has_many :child_tasks, :through => :from_tasks, :dependent => :destroy
  has_many :parent_tasks, :through => :to_tasks, :dependent => :destroy

  accepts_nested_attributes_for :to_tasks, :reject_if => :all_blank, :allow_destroy => true
  accepts_nested_attributes_for :from_tasks, :reject_if => :all_blank, :allow_destroy => true

TaskRelation.rb

  belongs_to :parent_task, :class_name => "Task",  :foreign_key => "task_from_id"
  belongs_to :child_task, :class_name => "Task", :foreign_key => "task_to_id"
  belongs_to :relation, :polymorphic => true

当我保存任务表单时,它还将tasks_tasks和子任务保存在task_relations表中,其relation_type为'Task',但我想将relation_type存储为父任务的'Parent'和子任务的'Child'。

任何人都可以帮助我。

1 个答案:

答案 0 :(得分:0)

首先,删除relation多态关联 - 不需要它。现在,将您的Task模型修改为如下所示:

# This association relates to tasks that are parents of self
has_many :parent_task_relations, class_name: 'TaskRelation', foreign_key: 'child_task_id'
# And this association relates to tasks that are children of self
has_many :child_task_relations, class_name: 'TaskRelation', foreign_key: 'parent_task_id'

has_many :child_tasks, :through => :child_task_relations
has_many :parent_tasks, :through => :parent_task_relations

你应该完成。

说明如何使用此功能 - 假设您有一个任务a,并且需要将任务B指定为父级,将任务C指定为子级。你可以这样做:

a.parent_tasks << b
a.child_tasks << c

这将对您的数据库产生与此代码相同的影响:

a.parent_task_relations.create(parent_task: b)
a.child_task_relations.create(child_task: c)

与(数据库)相同的是:

TaskRelation.create(parent_task: b, child_task: a)
TaskRelation.create(parent_task: a, child_task: c)