Использование области видимости только для отображения элементов, связанных с объектами - PullRequest
0 голосов
/ 28 октября 2011

Я использую meta_search для фильтрации списка автомобилей.Модель автомобиля определяется следующим образом:

class Car < ActiveRecord::Base
  has_many    :images, :class_name => "CarImage"
  ......
end

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

scope :with_images, joins(:images)

Если я пытаюсь выбрать только различные значения, например:

scope :with_images, joins(:images).select('DISTINCT cars.*')

... Я путаю другие методы, основанные на моих результатах поиска (такие как агрегаторы avg и count, с групповыми предложениями).

При просмотре Ruby on Rails Руководства , я нашел любопытный пример, который может решить мою проблему, но не могу заставить его работать, и я не совсем понимаю, как это делается:

scope :published_and_commented, published.and(self.arel_table[:comments_count].gt(0))

Если я использую self.arel_table[:images_count] тогда он говорит, что это нулевой объект.

Во всем приложении у нас действительно есть проблемы с поиском и фильтрацией с использованием атрибутов из таблиц ассоциации.Мы решили некоторые проблемы, просто переместив атрибут в основную таблицу cars, но это немного глупо, хотя и работает быстро.

После того, как я об этом подумал, на мой взгляд, было бы жизнеспособно:что ассоциация сначала получит список всех идентификаторов автомобилей в текущем поиске, которые имеют хотя бы одно изображение (это можно сделать с помощью простого запроса INNER JOIN и DISTINCT id), а затем использует список идентификаторов для полученияобычный запрос о листинге, но с предложением WHERE id IN [id_1, id_2, id_3, ... , id_n].

Вам это кажется разумным?И как бы я это сделал?: D

Кроме того, было бы неплохо, если бы я мог сделать это без SQL, просто с помощью Arel или MetaWhere ...

1 Ответ

2 голосов
/ 28 октября 2011

То, что вы нашли в руководствах по Rals, является самым простым и даже самым быстрым способом.

comments_count - это значение counter_cache, которое вы можете установить для ассоциаций, чтобы получить количество детей.

Реализуйте это легко:

has_many    :images, :class_name => "CarImage", :counter_cache => true

И тогда вы сможете получить доступ к предыдущему несуществующему images_count.

См. Документ .

...