рельсы многие ко многим самостоятельно присоединяются - PullRequest
14 голосов
/ 03 августа 2010

может кто-нибудь указать мне правильное направление:

Я пытаюсь построить модель для рельсов, которая построит следующее:

ClassA -id

ClassA имеетотношение ко многим "ClassA" (так что это ссылка на себя)

Я ищу миграцию и модель.

Я не уверен, что такое правильная таблица соединения (Iпредставьте себе простую таблицу из 2 столбцов ClassA_id, ClassARel_ID -> обе указывают на ClassA) и как построить модель

Спасибо!

Ответы [ 4 ]

30 голосов
/ 03 августа 2010

Я бы использовал что-то вроде

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
15 голосов
/ 05 января 2013

Если не имеет особого смысла создавать другой класс для объединения двух, альтернативный подход может быть:

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
1 голос
/ 22 ноября 2010

Этот пост имеет хороший рабочий пример: http://blog.hasmanythrough.com/2007/10/30/self-referential-has-many-through

Здесь также есть связанный вопрос: Проблема с самореференциальным has_many: через ассоциации в Rails

0 голосов
/ 02 июля 2016

К сожалению, ответ Уистлера может не подходить во многих случаях. Например, это не работает в обоих направлениях. Например, предположим, что вы создаете новое слово:

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.

Это говорит о том, что слово «вибрировать» не имеет синонимов.

Таким образом, в принципе, этот метод не будет работать в обоих направлениях (т. Е. Вибрация является синонимом дрожания, а дрожание - синоним вибрации)

Редактировать: В некотором смысле, вы можете использовать этот подход, однако вам придется явно назначать синонимы для каждого слова. Таким образом, хотя вы указали синонимы дрожания («вибрировать» и «встряхнуть»), вам все равно придется указывать синонимы «дрожания» («дрожать» и «вибрировать») и «вибрировать» (которые являются « дрожи и дрожи).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...