2012-03-04 2 views
1

Я использую Ruby on Rails 3.1, и я пытаюсь улучшить SQL-запрос, чтобы получить как «связанные» записи, так и связанные с ними записи (ActiveRecord::Associations), чтобы избежать запроса «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.

Как это сделать?


P.S .: Я улучшить запросы, например, следующие:

@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

Какой именно запрос вы собираетесь оптимизировать? – iltempo

+0

@iltempo - я обновил вопрос. – Backo

ответ

0

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

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

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

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

Обновлено

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

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

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

Но мне все еще любопытно, почему вы не пользуетесь ассоциацией Has and Belongs To Many.

+0

И если я использую некоторый оператор, включающий метод 'where', например:' Article.includes (: category_relationships =>: categories) .where (: user_id => 1) '? Я получаю одинаковые результаты (относительно производительности)? * BTW *: Как работает 'includes()'? – Backo

+0

Я обновил вопрос. – Backo

Смежные вопросы