Соединения с активными записями - 3 основных таблицы, 2 таблицы объединения - PullRequest
2 голосов
/ 30 ноября 2011

Настройка

У меня есть модель данных с 3 основными таблицами (пользователи, ссылки, темы) с 2 таблицами соединения (link_saves и link_topics). Мои модели:

Пользователь

has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'user_id'
has_many :links, :through => :link_saves

LinkSave

belongs_to :user
belongs_to :link

Link

has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'link_id'
has_many :users, :through => :link_saves

has_many :link_topics, :inverse_of => :link
has_many :topics, :through => :link_topics

LinkTopic

belongs_to :link
belongs_to :topic

Тема

has_many :link_topics
has_many :links, :through => :link_topics

Вопрос

Я хочу найти список всех тем, ссылки на которые пользователь сохранил. Я хотел бы иметь возможность сделать @user.topics и прыгать через все 5 таблиц от пользователя до тем. Что еще более важно, я хочу, чтобы это возвращало отношение ActiveRecord, чтобы я мог расширять / сортировать / публиковать список пользовательских тем далее, чтобы это НЕ работало:

## app/models/user.rb

def topics
  links.collect(&:topics)
end

Я иду по неверному пути? Есть ли способ сделать это через активную запись без необходимости писать все пользовательские SQL? Помогите пожалуйста!

Возможные ответы (обновление)

Использование нескольких has_many :through с для создания всех прыжков. Это работает, но не может быть лучшей практикой, верно?

## app/models/user.rb
has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'user_id'
has_many :links, :through => :link_saves
has_many :link_topics, :through => :links, :uniq => true
has_many :topics, :through => :link_topics, :uniq => true

1 Ответ

0 голосов
/ 30 ноября 2011

Я думаю, что это называется «вложенным» has_many, проходящим от A к B и C.

В Rails 3.1 эта функциональность теперь поддерживается http://www.warmroom.com/yesterdays/2011/08/30/rails-3-1-nested-associations/

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html (ищите 'Nested')

Пример, который у них есть, немного проще, чем у вас, но я думаю, вам будет достаточно получить некоторые идеи.

class Author < ActiveRecord::Base
  has_many :posts
  has_many :comments, :through => :posts
  has_many :commenters, :through => :comments
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :commenter
end

@author = Author.first
@author.commenters # => People who commented on posts written by the author

До Rails 3.1 был плагин 'https://github.com/releod/nested_has_many_through'

...