Как сделать запрос ActiveRecord, чтобы получить элемент, общий для нескольких других элементов
Я пытаюсь изменить Sharetribe, платформу Ruby on Rails для онлайн-сообществ. Есть этот метод, который возвращает мне соответствующие поисковые фильтры.
На данный момент, он возвращает мне фильтр, если он присутствует в любой из категорий (обозначенных category_ids
)
Я хотел бы, чтобы он возвращал фильтр, если и только если он присутствует во ВСЕХ категориях, определенных category_ids
,
Будучи новичком в Rails и ActiveRecord, я немного растерялся. Вот метод, возвращающий соответствующие фильтры:
# Database select for "relevant" filters based on the `category_ids`
#
# If `category_ids` is present, returns only filter that belong to
# one of the given categories. Otherwise returns all filters.
#
def select_relevant_filters(category_ids)
relevant_filters =
if category_ids.present?
@current_community
.custom_fields
.joins(:category_custom_fields)
.where("category_custom_fields.category_id": category_ids, search_filter: true)
.distinct
else
@current_community
.custom_fields.where(search_filter: true)
end
relevant_filters.sort
end
Есть ли способ изменить запрос SQL, или я должен получить все поля, как это происходит сейчас, а затем удалить те, которые мне не интересны?
2 ответа
Поэтому я решил свою проблему, выбрав фильтры, которые присутствуют во всех подкатегориях выбранной категории. Для этого я выбираю все фильтры всех подкатегорий и оставляю только те из них, которые возвращаются количество раз, в точности равными количеству подкатегорий.
all_relevant_filters = select_relevant_filters(m_selected_category.own_and_subcategory_ids.or_nil)
nb_sub_category = m_selected_category.subcategory_ids.size
if nb_sub_category.none?
relevant_filters = all_relevant_filters
else
relevant_filters = all_relevant_filters.select{ |e| all_relevant_filters.count(e) == nb_sub_category.get }.uniq
end
Попробуйте следующее
def select_relevant_filters_if_all(category_ids)
relevant_filters =
if category_ids.present?
@current_community
.custom_fields
.joins(:category_custom_fields)
.where("category_custom_fields.category_id": category_ids, search_filter: true)
.group("category_custom_fields.id")
.having("count(category_custom_fields.id)=?", category_ids.count)
.distinct
else
@current_community
.custom_fields.where(search_filter: true)
end
relevant_filters.sort
end
Это новый метод в вашем HomeController
Обратите внимание, что название отличается, просто чтобы пропустить monkeypatching. Комментарии приветствуются.