Как извлечь как «связанные» записи, так и «связанные через» записи быстрым способом? - PullRequest
1 голос
/ 04 марта 2012

Я использую Ruby on Rails 3.1 и пытаюсь улучшить SQL-запрос для извлечения как «связанных» записей, так и «связанных через» записей (ActiveRecord::Associations) быстрым способом, чтобы избежать «* 1002»* N + 1 проблема запроса".То есть у меня есть:

class Article < ActiveRecord::Base
  has_many :category_relationships

  has_many :categories,
    :through => :category_relationships
end

class Category < ActiveRecord::Base
  has_many :article_relationships

  has_many :articles,
    :through => :article_relationships
end

В паре SQL-запросов (т. Е. «Быстрым способом», возможно, с использованием метода Ruby on Rails includes()) Я бы хотелчтобы получить и categories и category_relationships, или оба articles и article_relationships.

Как я могу это сделать?


PS: я улучшаю запросы, подобные следующим:

@category = Category.first

articles = @category.articles.where(:user_id => @current_user.id)
articles.each do |article|
  # Note: In this example the 'inspect' method is just a method to "trigger" the
  # "eager loading" functionalities
  article.category_relationships.inspect
end

1 Ответ

0 голосов
/ 04 марта 2012

Вы можете сделать

Article.includes(:category_relationships => :categories).find(1)

, что уменьшит это до 3 запросов (1 для каждой таблицы).Для производительности также убедитесь, что ваши внешние ключи имеют индекс.

Но в целом мне любопытно, почему сущность "category_relationships" вообще существует, и почему это не ситуация типа has_and_belongs_to?

Обновлено

В соответствии с измененным вопросом вы все равно можете сделать

Category.includes(:article_relationships => :articles).first

Если вы смотрите консоль (или хвостовой журнал / разработка)вы увидите, что когда вы вызываете ассоциации, он попадет в кешированные значения, и вы золотые.

Но мне все еще любопытно, почему вы не используете ассоциацию «Имеет и принадлежит многим».

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