2013-09-17 5 views
4

Я ищу, чтобы написать запрос ActiveRecord, и это то, что у меня есть. К сожалению, вы не можете использовать ИЛИ, как это. Каков наилучший способ выполнения? category_ids - это массив целых чисел.Rails ActiveRecord где или статья

.where(:"categories.id" => category_ids).or.where(:"category_relationships.category_id" => category_ids) 
+0

Это также неправильное использование символа 'hash',': ' – lurker

+0

, какую таблицу вы пытаетесь извлечь, категорию или что-то еще, связанное с ней? – tihom

+0

Возможный дубликат [запроса ActiveRecord OR] (http://stackoverflow.com/questions/3639656/activerecord-or-query) – user

ответ

14

Один из способов - вернуться к сырцовому ...

YourModel.where("categories.id IN ? OR category_relationships.category_id IN ?", category_ids, category_ids) 
-3

То, что вы хотите сделать, это вручную писать или часть запроса, как это:

.where("category.id in (#{category_ids.join(',')}) OR category_relationships.category_id in (#{category_ids.join(',')})")

+4

Некоторые рекомендации по безопасности: если вы не можете полностью доверять всем вашим параметрам запроса, лучше использовать экранированный синтаксис запроса, например 'where (" categories.id IN (?) ИЛИ category_relationships.category_id IN (?) ", category_ids, category_ids)'. – florish

7

Держите SQL из него и использовать Arel, как это:

.where(Category.arel_table[:id].in(category_ids). 
    or(CategoryRelationship.arel_table[:category_id].in(category_ids)) 
+4

Хотя это забавно и аккуратно, чтобы абстрагироваться от SQL, трудно добиться каких-либо успехов. Я бы сказал, что читать гораздо труднее. Если вы пытаетесь скомпилировать свой Ruby при сборке, вы можете поймать ошибки, но ваши тесты RSpec также поймают эти ошибки. Вы писали тесты, верно? –

+1

AREL - идеальный образец анти-шаблона для людей, которые хотят применить принцип KISS. –

0

Предполагая, что вы хотите вернуть категории, вам нужно ВРУЧИТЬ ОБЪЯВЛЕНИЕ category_relationships и поместить условие ИЛИ в комбинированную таблицу.

Category.includes(:category_relationships).where("categories.id IN (?) OR category_relationships.category_id IN (?)",category_ids,category_ids) 

Этот запрос создает внешнее соединение таблицы путем объединения столбцов categories и category_relationships. В отличие от внутреннего соединения (например, Category.joins(:category_relationships)), таблица внешнего соединения также должна иметь categories без ассоциированных category_relationship. Затем он применил бы условия в предложении where на внешней таблице соединений, чтобы вернуть соответствующие записи.

includes заявление без условий в ассоциации обычно делает два отдельных запроса sql для извлечения записей и их связи. Однако при использовании с условиями в связанной таблице он должен сделать один запрос для создания внешней таблицы соединений и запуска условий на внешней таблице соединений. Это позволяет вам извлекать записи без ассоциации.

См. this для подробного объяснения.

Смежные вопросы