Как получить информацию из третьей таблицы при объединении двух таблиц? - PullRequest
2 голосов
/ 02 апреля 2012

У меня есть эта схема:

enter image description here

  • Есть таблица для персон.
  • У каждого человека есть одна таблица "информации".
  • Люди могут иметь друзей.Это хранится в другой таблице, называемой «друзья», в которой есть внешний ключ для человека, и еще один для его друга (оба указывают на таблицу «человек»).

Модель "персона":

class Person < ActiveRecord::Base
  has_one :info
  has_many :friends
end

Модель "инфо":

class Info < ActiveRecord::Base
  belongs_to :person

  attr_accessible :description
end

Модель "друзей":

class Friend < ActiveRecord::Base
  belongs_to :person

  attr_accessible :friend_id
end

Предположим, у нас есть 2 человека: person1 и person2.Каждый с записью в таблице «info» хранит свое описание.И давайте предположим, что person2 является другом person1.

содержимое таблицы "person":

id: 1

id:2

содержимое таблицы "info":

id: 1, person_id: 1, описание: "Это человек 1, наш главныйчувак. "

id: 2, person_id: 2, описание:" Это человек 2, наш второстепенный чувак. "

содержание таблицы" друзей ":

id: 1, person_id: 1, friend_id: 2

Если я хочу получить друзей person1, я делаю это:

Person.first.friends

Это даст мне:

id: 1, person_id: 1, friend_id: 2

Теперь, как мне добавить контент "info" для каждой строки?

Ответы [ 2 ]

1 голос
/ 03 апреля 2012

Вы пытались использовать встроенную в Rails функцию привязки запросов?

С http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

Это должно быть что-то вроде Person.first.friends.includes(:info)

Обновление: Ах, вы хотите, чтобы информация о Друзьях, и в модели нет связи, чтобы получить это прямо сейчас.

Похоже, вам не хватает ассоциации, чтобы получить модель Person для друга (а не для пользователя). Что-то вроде:

class Friend < ActiveRecord::Base
  belongs_to :person
  belongs_to :friendly_person, :class_name => "Person", :foreign_key => "friend_id"
end

Затем вы можете использовать ассоциации, которые вы создали с включениями, аналогичными ранее Person.first.friends.includes(:friendly_person => :info), и это должно вернуть информацию для друга.

Еще одно обновление: для доступа к информационному столбцу для friendly_person вы можете использовать ассоциацию. Как в friendly_person.info.description. Вы не можете сделать это в коллекции (очевидно), у вас должен быть экземпляр человека. Что-то вроде Person.first.friends.includes(:friendly_person => :info).first.friendly_person.info.description ... но я хотел бы отметить, что этот тип кода не считается хорошей практикой.

1 голос
/ 02 апреля 2012

Вот первое решение, с которым я пришел:

Friends.select("p.description").joins("INNER JOIN info i ON i.person_id = friend_id").where(person_id: 1)

Кто-нибудь с лучшим / более ясным / более эффективным?

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