Как объединить области в Ruby on Rails 3? - PullRequest
3 голосов
/ 25 февраля 2012

Я довольно новичок в Rails, и я не могу разобраться в этом:

У меня есть различные проекты , принадлежащие различным клиентам .

В моей модели Project у меня есть две функции поиска:

scope :search_by_name, lambda { |fn| where('name LIKE ?', "%#{fn}%") }

scope :search_by_client, lambda { |fn| where('client_id LIKE ?', fn) }

Оба, похоже, работают. Например, в URL, который я могу передать в этом запросе:

/projects?search_by_name=fooproject

Я также могу сделать это:

/projects?search_by_client_name=misterx

Это даст все Проекты , принадлежащие Клиенту MisterX.

Теперь есть способ объединить эти две функции поиска, чтобы запрос

/projects?search=foofoo

будет извлекать проекты с именем foofoo , а также проекты, принадлежащие клиентам с именем foofoo ?

Спасибо за любую помощь!

1 Ответ

7 голосов
/ 25 февраля 2012

В SQL вы можете выполнять поиск по нескольким условиям. Вы определили две области, и они могут быть объединены в цепочку следующим образом:

Project.search_by_name('fooproject').search_by_client('misterx')

Это создает следующий SQL:

SELECT "projects".* FROM "projects" WHERE "projects".name LIKE '%fooproject%' AND "projects".client_id LIKE '%misterx'

Оператором, объединяющим эти два условия, является «И», что означает, что результатом будут те, которые удовлетворяют обоим условиям, а не любому условию.

Есть несколько способов получить проекты с определенным именем или проекты, принадлежащие клиенту. Самый простой способ - создать новую область видимости, в которой указан оператор OR:

scope :search_by_name_or_client, lambda { |name, client| where('name LIKE ? OR client_id LIKE ?', "%#{name}%", "%#{client}%") }

Возможно, вы также захотите взглянуть на SQL UNION, которые объединяют результирующий набор из двух или более операторов выбора. ActiveRecord не обрабатывает функциональность UNION, но существуют гемы для расширения функциональности, включающие это, такие как https://github.com/tsmango/union

И пример написания этого с использованием самоцвета Союза будет выглядеть так:

Project.union([{:conditions => ['name like ?', "%#{name}%"]}, {:conditions => ['client like ?', "%#{client}%"]}])

Это приведет к созданию следующего SQL:

SELECT "projects".* FROM "projects" WHERE "projects".name LIKE '%fooproject%'
UNION
SELECT "projects".* FROM "projects" WHERE "projects".client_id LIKE '%misterx'

Более подробную информацию о SQL UNION можно найти здесь: http://www.w3schools.com/sql/sql_union.asp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...