Создание модели с древовидной структурой
У меня есть категории, которые находятся в древовидной структуре. Я пытаюсь связать их вместе, определяя родителя для каждого из них. (Я не мог понять, как вызвать свойство parent
, так что теперь он просто category
, но это означает родительский элемент).
class Category < ActiveRecord::Base
has_one :category # the parent category
end
Но отношения заканчиваются неправильным образом.
Функция getter находится в дочерней категории (правильно), но category_id
хранится в родительском объекте:
parent = Category.create(:name => "parent")
child = Category.create(:name => "child", :category => parent)
parent.id # 1
child.id # 2
child.category_id # nil
parent.category_id # 2
child.category.name # "parent" (!!)
Родитель должен иметь несколько дочерних элементов, поэтому это не будет работать.
Ответы
Ответ 1
То, что вы ищете, - это присоединение к себе. Проверьте этот раздел руководства Rails: http://guides.rubyonrails.org/association_basics.html#self-joins
class Category < ActiveRecord::Base
has_many :children, class_name: "Category", foreign_key: "parent_id"
belongs_to :parent, class_name: "Category"
end
Каждая категория будет belong_to
родителем, даже родительскими. Вы можете создать родителя одной категории, к которому принадлежат все категории высшего уровня, тогда вы можете игнорировать эту информацию в своем приложении.
Ответ 2
Для достижения этой цели вы можете использовать act_as_tree gem, найти ниже пример и ссылку.
https://github.com/amerine/acts_as_tree/tree/master
class Category < ActiveRecord::Base
include ActsAsTree
acts_as_tree order: "name"
end
root = Category.create("name" => "root")
child1 = root.children.create("name" => "child1")
subchild1 = child1.children.create("name" => "subchild1")
root.parent # => nil
child1.parent # => root
root.children # => [child1]
root.children.first.children.first # => subchild1
Ответ 3
Категория должна иметь много категорий, а внешний ключ каждой категории должен быть parent_id
. Итак, когда вы делаете parent.children
, он перечисляет все категории с parent_id=parent.id
.
Вы читали о наследовании одиночной таблицы?
Ответ 4
Вы должны взглянуть на родословную: https://github.com/stefankroes/ancestry
Он предоставляет всю необходимую функциональность и способен вывести всех потомков, братьев и сестер, родителей и т.д. с помощью одного SQL-запроса, используя вариант материализованных путей, чтобы он имел лучшую производительность, чем ответы self-joins и actions_as_tree выше.