В Rails, как я могу сделать ассоциации ActiveRecord для двух моделей, которые ссылаются друг на друга по-разному? - PullRequest
1 голос
/ 17 ноября 2011

Я использую Rails 3.1. У меня есть модель Tree и модель TreeNode, и я установил связь has_many / own_to между Tree и TreeNodes.

# The initial models and associations.

class Tree < ActiveRecord::Base
  has_many :tree_nodes
end

class TreeNode < ActiveRecord::Base
  belongs_to :tree
end

Я хочу добавить концепцию корневого узла, который не обязательно является узлом, который был создан первым. Я не могу неявно определить корневой узел по методу create_date, первичному ключу (id) или порядку (поскольку отсутствует понятие порядка с узлами). Я пытаюсь обдумать, как настроить эту ассоциацию в Rails.

Я начал с добавления столбца root_node с внешним ключом в таблицу Tree, но тогда моей ассоциацией Active Record будет Tree Tree_to Node и Node has_one Tree. Это связано с тем, что класс, имеющий внешний ключ, должен иметь ассоциацию «own_to», а другой класс должен иметь ассоциацию «has_one». Мне это не кажется правильным.

# This code didn't work.

class Tree < ActiveRecord::Base
  has_many :script_steps
  belongs_to :root_tree_node, :class => 'TreeNode'
end

class TreeNode < ActiveRecord::Base
  belongs_to :tree
  has_one :tree
end

Я также пытался создать таблицу соединений с has_one: through, но ассоциации тоже не сработали.

# This code didn't work.

class Tree < ActiveRecord::Base
  has_many :script_steps
  has_one :root_node, :class => 'TreeNode', :through => :root_tree_node
end

class TreeNode < ActiveRecord::Base
  belongs_to :tree
  has_one :root_tree_node
end

# This represents the join table.
class RootTreeNode < ActiveRecord::Base
  belongs_to :tree
  belongs_to :tree_node
end

Каков, вообще говоря, лучший способ моделирования этих отношений и как лучше установить ассоциации в ActiveRecord? В конце концов, я хочу иметь возможность сделать что-то вроде этого.

tree = Tree.create
some_node = tree.tree_nodes.create
another_node = tree.tree_nodes.create

tree.root_node = another_node
tree.save

1 Ответ

0 голосов
/ 17 ноября 2011

Хмм ... Если вы пытаетесь получить нормальную древовидную структуру, как, например, дерево категорий, один из способов сделать это в рельсах такой:

def Category < ActiveRecord::Base
  belongs_to :parent, :class_name => "Category", :foreign_key => :parent_id
end

Это означает, что каждая строка имеет ссылку на своего родителя. Корневой узел - это узел с

parent_id == nil

Конечный узел - это когда его идентификатор никогда не используется в качестве parent_id. За дополнительной информацией обращайтесь к плагину acts_as_tree (не уверен, работает ли он с рельсами 3).

Другой вариант, который вы можете найти более полезным, это nested_set (подробнее здесь )

...