ограничить количество объектов, возвращаемых в has_many - PullRequest
9 голосов
/ 20 мая 2011

Как я могу ограничить количество строк, возвращаемых в множестве отношений? Например:

class User < ActiveRecord::Base
  has_many :photos
end

Я хочу иметь возможность:

User.includes(:photos => {:limit => 8}).all

Это явно не работает, но что-то с этим функционалом. Нужно ли сам писать SQL?

Заранее спасибо!

EDIT: Я не хочу ограничивать ассоциацию, только результаты запроса. Таким образом, у пользователя может быть тысяча фотографий, я хочу, чтобы вернулись только первые три.

Ответы [ 3 ]

10 голосов
/ 17 ноября 2012

Вам не нужно жестко задавать ограничение в модели. Вы можете позвонить @user.photos.limit(8). Вы также можете вызвать @user.photos.scoped, чтобы получить объект области видимости, который выполняет отложенную загрузку. То, что вернулось из @user.photos, может выглядеть очень, очень похоже на Array, но это не так - оно врет вам!

См. http://apidock.com/rails/ActiveRecord/Associations/CollectionProxy об интересном путешествии в кроличью нору. Вы получаете возможность делегировать практически все стандартные вызовы проверки объектов (class, singleton_class, methods, method и т. д.) к объекту Array, но он делегирует определенный набор вызовов объекту ActiveRecord::Associations::*. Вот почему, если вы позвоните @user.photos.method(:<<), он скажет вам, что использует #<Method: Array#<<>, но на самом деле он не использует это - он использует тот, что в ActiveRecord::Associations::CollectionProxy!

2 голосов
/ 20 мая 2011

Просто добавьте предельную опцию к ассоциации has_many:

class User < ActiveRecord::Base
  has_many :photos, :limit => 8
end

EDIT

В соответствии с вашими потребностями:

class User < ActiveRecord::Base
  has_many :all_photos, :class_name => "Photo"
  has_many :photos, :limit => 8
end

примечание: изменено «class» на «class_name» в ассоциации all_photos

2 голосов
/ 20 мая 2011

Вы можете поставить :limit на фактическую has_many декларацию.

class User < ActiveRecord::Base
  has_many :photos, :limit => 8
end
...