Використовуйте область, щоб відображати лише ті елементи, які мають пов'язані об'єкти

Я використовую 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.*')

... Я перекручую інші методи, які покладаються на мої результати пошуку (наприклад, агрегатори середнього та середнього рівня, з груповими пунктами).

Під час перегляду посібників з 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 ...

0

1 Відповіді

Те, що ви знайшли в керівництві Rals, це найпростіший спосіб пройти і навіть найшвидший.

comments_count is a counter_cache htat you can set on associations to get the number of children.

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

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

І тоді ви зможете отримати доступ до попереднього неіснуючого images_count .

See doc.

2
додано
Приємно! Я зараз читаю про counter_cache: RailsCasts . Схоже, я повинен додати новий стовпець до таблиці з міграцією ... До цих пір я отримав Невідомий ключ (и): counter_cache , якщо я просто додати його, як ви пропонуєте.
додано Автор Cristian, джерело
Так, я забув про міграцію шкода :) Це також пояснюється в документі.
додано Автор apneadiving, джерело