Rails самореферентный через has_many с пользовательским именованием таблицы соединений
У меня есть некоторые проблемы, оборачивающие мою голову вокруг следующей ситуации..
Я пытаюсь создать древовидную структуру, где я смогу дать пользовательские имена для соединений между узлами..
Поэтому я хочу иметь модели Node и Relation. каждый
Node
has_many :relations
каждый
Relation
has_many :nodes
Узел может быть либо родителем, либо потомком. Пока что все было просто, и есть множество примеров, показывающих, как создать самореференциальную таблицу has_many... Проблема в том, что я хочу иметь возможность давать имена отношениям. так что я могу сделать что-то вроде:
relation1 = node1.relations.create(:name => "relation_name", :child => node2)
и в результате получить что-то вроде:
relation1.name == "relation_name"
relation1.parent == node1
relation1.child == node2
Все творения происходят внутри модели, эта деятельность не подвергается действию пользователя, если это имеет значение. Спасибо!
EDIT2: Вот как это работает сейчас:
class Node < ActiveRecord::Base
belongs_to :sentence
has_one :parent_relation, :foreign_key => "child_id", :class_name => "Relation"
has_many :child_relations, :foreign_key => "parent_id", :class_name => "Relation"
has_one :parent, :through => :parent_relation
has_many :children, :through => :child_relations, :source => :child
has_many :relations, :foreign_key => "child_id"
has_many :relations, :foreign_key => "parent_id"
class Relation < ActiveRecord::Base
has_many :videos, :as => :videoable, :dependent => :destroy
has_many :phrases, :through => :videos
belongs_to :parent, :class_name => "Node"#, :inverse_of => :parent_relation
belongs_to :child, :class_name => "Node"#, :inverse_of => :child_relation
1 ответ
Так что то, о чем вы говорите, больше похоже на модель соединений, чем на самоссылку.
Примечание: я изменил ваш relation
ассоциация "ярлыки", потому что мне было трудно с вашими именами, поэтому вам не нужно менять "ярлыки", которые были только для меня.
Так что для вашего Node
класс вы могли бы сделать что-то вроде этого
class Node < ActiveRecord::Base
has_one :parent_relation, :foreign_key => "child_id",
:class_name => "Relation"
has_many :child_relations, :foreign_key => "parent_id",
:class_name => "Relation"
has_one :parent, :through => :parent_relation
has_many :children, :through => :child_relations, :source => :child
end
Тогда для вашего Relation
класс вы могли бы что-то вроде
class Relation < ActiveRecord::Base
belongs_to :parent, :class_name => "Node", :inverse_of => :parent_relation
belongs_to :child, :class_name => "Node", :inverse_of => :child_relations
end
:inverse_of
опция должна позволять вам строить Node
основанный на parent
а также children
ассоциации от вашего Node
случаи, это просто предостережение от магии с :through
отношения. (Документация по этому вопросу находится внизу раздела " Модель соединений ".)
Я не совсем понимаю вашу структуру ассоциации, но я думаю, что это должно правильно моделировать ее. Позвольте мне знать, если есть какие-либо проблемы, хотя.
Примечание стороны: с Relation
постоянное множество в ActiveRecord
модуль, который вы могли бы рассмотреть вопрос об изменении его на что-то вроде NodeRelationship
, Я не думаю, что это будет мешать вашей программе, но это определенно вызвало некоторые проблемы для моего мыслительного процесса.