Rails стремятся к нагрузке и пределу - PullRequest
6 голосов
/ 21 марта 2012

Я думаю, что мне нужно что-то похожее на загруженный рельсами запрос с ограничением, но у меня возникли проблемы с поиском решения для этого.

Ради простоты, скажем, что в системе никогда не будет более 30 Person с (поэтому Person.all - это небольшой набор данных), но у каждого человека будет более 2000 комментариев (поэтому Person.include(:comments) будет большой набор данных).

Родительская ассоциация

class Person < ActiveRecord::Base
  has_many :comments
end

Детское объединение

class Comment < ActiveRecord::Base
  belongs_to :person
end

Мне нужно запросить список Person с и включить их comments, но мне нужно только 5 из них.

Я бы хотел сделать что-то вроде этого:

Ограниченная родительская ассоциация

class Person < ActiveRecord::Base
  has_many :comments
  has_many :sample_of_comments, \
    :class_name => 'Comment', :limit => 5
end

Контроллер

class PersonController < ApplicationController
  def index
    @persons = Person.include(:sample_of_comments)
  end
end

К сожалению, эта статья гласит: «Если вы хотите загрузить ассоциацию с указанным параметром: limit, она будет проигнорирована, возвращая все связанные объекты»

Есть ли хороший способ обойти это? Или я обречен выбирать между энергичной загрузкой 1000 ненужных объектов ActiveRecord и запросом N + 1? Также обратите внимание, что это упрощенный пример. В реальном мире у меня будут другие ассоциации с Person, в том же действии index с той же проблемой, что и comments. (фотографии, статьи и т. д.).

1 Ответ

0 голосов
/ 09 апреля 2012

Независимо от того, что сказано в «этой статье», проблема в SQL, вы не можете сузить второй запрос sql (нетерпеливой загрузки) так, как вы хотите в этом сценарии, просто используя стандартный LIMIT

Однако вы можете добавить новый столбец и выполнить вместо него предложение WHERE

  1. Измените вторую ассоциацию на Person has_many :sample_of_comments, conditions: { is_sample: true }
  2. Добавление столбца is_sample в таблицу comments
  3. Добавить Comment#before_create хук, который назначает is_sample = person.sample_of_comments.count < 5
...