Рельсы от многих до многих
может ли кто-нибудь указать мне в правильном направлении:
Я пытаюсь создать модель для рельсов, которые создают следующее:
ClassA -id
ClassA имеет отношение ко многим "ClassA" (так что это ссылка на себя)
Я ищу миграцию и модель.
Я не уверен, какая правильная таблица соединений (я думаю, что ее простая таблица с двумя столбцами ClassA_id, ClassARel_ID → оба указывают на ClassA) и как построить модель
Спасибо!
Ответы
Ответ 1
Я бы использовал что-то вроде
class Person < ActiveRecord::Base
has_many :friendships, :foreign_key => "person_id",
:class_name => "Friendship"
has_many :friends, :through => :friendships
end
class Friendship < ActiveRecord::Base
belongs_to :person, :foreign_key => "person_id", :class_name => "Person"
belongs_to :friend, :foreign_key => "friend_id", :class_name => "Person"
end
И таблицы будут похожи на
people: id; name; whatever-you-need
friendships: id; person_id; friend_id
Ответ 2
Если не создать слишком много смысла для создания другого класса, чтобы присоединиться к ним, альтернативный подход может быть:
class Word < ActiveRecord::Base
has_and_belongs_to_many :synonyms, class_name: "Word",
join_table: "word_synonyms",
association_foreign_key: "synonym_id"
end
Таблица соединений будет выглядеть так:
create_table :word_synonyms do |t|
t.integer :word_id
t.integer :synonym_id
end
Ответ 3
У этого сообщения есть хороший рабочий пример:
http://blog.hasmanythrough.com/2007/10/30/self-referential-has-many-through
Здесь есть и связанный с этим вопрос:
Проблема с self-referential has_many: через ассоциации в Rails
Ответ 4
К сожалению, ответ Уистлера может оказаться неприемлемым во многих случаях. Например, это не работает в обоих направлениях. Например, предположим, что вы создаете новое слово:
word = Word.create(:word_name => 'tremble')
['shake', 'vibrate'].each { |syn| word.synonyms.create(:word_name => syn) }
Теперь, если вы это сделаете:
word = Word.find_by_word_name('tremble')
p word.synonyms # this would print out the Words with the word_name 'shake' and 'vibrate'.
Однако,
если вы сделали это наоборот:
word = Word.find_by_word_name('vibrate')
p word.synonyms # this would print an empty association.
Это говорит, что слово "вибрировать" не имеет синонимов.
В принципе, этот метод не будет работать в обоих направлениях (т.е. вибрация является синонимом дрожания, а дрожь - синоним вибрации)
Изменить: в некотором смысле, вы можете использовать этот подход, однако вам придется явно назначать синонимы для каждого слова. Поэтому, хотя вы указали синонимы дрожания (которые "вибрируют" и "встряхиваются" ), вам придется по-прежнему указывать синонимы "дрожания" ( "которые дрожат" и "вибрируют" ) и "вибрируют" (которые "дрожать и дрожать" ).