Можно ли выполнить запрос find_by_sql в Rails / ActiveRecord без загрузки всех результатов в память? - PullRequest
1 голос
/ 25 октября 2010

Я создаю плагин Rails, который извлекает много данных из приложений Rails.Он строит запросы динамически, которые охватывают несколько таблиц, и будет возвращено много результатов.Вот пример одного из запросов, созданных для извлечения данных покупки из Spree (корзина покупок Rails):

select orders.user_id as from_id, variants.product_id as to_id from orders, line_items, variants where orders.user_id is not null and variants.product_id is not null and orders.id = line_items.order_id and line_items.variant_id = variants.id order by from_id;

Проблема в том, что ActiveRecord загружает все результаты в память.Есть ли способ избежать этого, не переходя к написанию специфичного для БД кода?(Я знаю о find_each, но это не позволяет сортировать.)

Ответы [ 3 ]

2 голосов
/ 26 октября 2010

Это определенно возможно, и вот статья, которая проходит через это:

http://www.rubyinside.com/paginate_by_sql-rails-pagination-on-your-own-sql-queries-50.html

У них есть код, который вы можете скопировать дословно, но ключ использует метод SQL count. С помощью этого кода вы можете позвонить paginate_by_sql вместо find_by_sql, и вы передадите параметры страницы и страницы.

0 голосов
/ 26 октября 2010

Ответ Хайме привел меня к более продуктивному пути запросов, приземляющихся на will_paginate , который предлагает метод paginate_by_sql.С небольшим усилием, которое было завернуто в разбитый на страницы SQL каждый:

def paginated_sql_each(query, &block)
  page = 1
  begin
    results = paginate_by_sql(query, :page => page)
    results.each { |r| block.call(r) }
    page += 1
  end while !results.empty?
end
0 голосов
/ 26 октября 2010

Возможно, вы также захотите изучить пакеты Rails ActiveRecord для получения записей меньшими порциями:

http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects-in-batches

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