Создать поиск по атрибутам нескольких таблиц - PullRequest
1 голос
/ 12 октября 2019

Я использую globalize gem , чтобы добавить сводку на мой сайт

, и у меня сложная проблема, у меня есть поисковая система для фильтрации действий

этодве мои модели:

class Activity < ActiveRecord::Base
  belongs_to :category

  translates :name, :description
end

class Category < ActiveRecord::Base
  has_many :activities

  translates :name
end

Я сгенерировал их таблицы с гемом, у меня есть activities и activity_translations, categories и category_translations

Поля, которые я хочуtranslate (вы можете видеть в их моделях) находятся в их таблицах перевода, если я хочу найти activities или categories по имени, я должен искать их в их таблицах перевода

для действий, это легко:

activities = Activity.with_translations.where(event_id: event_id)
activities = activities.where('activity_translations.name LIKE :query', query: "%#{query}%")

но моя проблема в том, что я хочу отфильтровать activities по name и categories по name с тем же запросом, для этого мне нужно ввести их таблицы перевода,так же, как категории в действиях являются необязательными

я пытаюсь это:

activities = Activity.with_translations.where(event_id: event_id)
activities = activities
                       .joins("LEFT OUTER JOIN categories ON activities.category_id = categories.id INNER JOIN category_translations ON category_translations.category_id = categories.id")
                       .where('activity_translations.name LIKE :query OR activity_translations.description LIKE :query OR category_translations.name LIKE :query', query: "%#{query}%")

но это не работает, просто возвращает мне действия, которые имеют категории

какие-либо предложения?

1 Ответ

0 голосов
/ 14 октября 2019

Diclaimer: Я никогда не использовал камень глобализации, поэтому ваш пробег может варьироваться.

Вы можете сделать это с помощью двух подвыборов вместо объединений.

SELECT activities.* FROM activities 
WHERE activities.id IN 
  (SELECT activity_translations.activity_id FROM activity_translations WHERE activity_translations.name LIKE :query)
OR activities.category_id IN 
  (SELECT category_translations.category_id FROM category_translations WHERE category_translations.name LIKE :query)

Я просто предполагаю, что в таблице переводов есть столбец x_id, который указывает назад.

Вы можете воспроизвести этот запрос в ванильном ActiveRecord с помощью чего-то вроде:

Activity.where(
  id: ActivityTranslation.select(:activity_id)
        .where('name LIKE ?', "%#{query}%"))
.or(
  Activity.where(
    category_id: CategoryTranslation.select(:activity_id))
       .where('name LIKE ?', "%#{query}%"))
)
...