Как вы делаете Rails 3 выберите IN, используя предложения where - PullRequest
23 голосов
/ 07 июня 2011

Я использую Rails 3, и мне нужно сделать выбор, где первичный ключ записей IN в результате предыдущего выбора.Вы можете сделать это легко, используя прямой SQL, используя IN.Вот явно неправильный способ, которым я сделал то, что мне нужно.Как Rails может сделать это хорошо:

@task = Link.find(params[:id])
clients = Client.where('task_id = ?',@task.id).select('DISTINCT(company_id)')
company_list = []
clients.each do |client|
  company_ids << client.company_id
end
@companies = Company.where(:id => company_ids)

Ответы [ 5 ]

38 голосов
/ 01 ноября 2012

Как уже упоминали другие, я бы использовал join в этом случае. Синтаксис использования «in» также очень прост, например,

company_ids = [1,2,3,4]
@companies = Company.where("id in (?)", company_ids)

Обновление

На самом деле это даже проще, чем сейчас (я думаю, рельсы 3+), вы можете сделать

company_ids = [1,2,3,4]
@companies = Company.where(id: company_ids)
6 голосов
/ 07 июня 2011

Это не отвечает на ваш вопрос о «выберите IN, используя условия where», но я думаю, что весь ваш сценарий можно переписать в одну строку, используя joins.Это должно дать тот же результат, что и ваш фрагмент выше:

@companies = Company.joins(:clients).where(:clients => {:task_id => params[:id]})
1 голос
/ 07 июня 2011

Я полагаю, что это будет делать то, что вы просите:

@task      = Link.find(params[:id])
@companies = Company.where(:id => Client.where(:task_id => @task.id).select('distinct company_id').map(&:company_id))

Вы можете просмотреть sql, нажав .to_sql в конце консоли.

Синтаксис объединения в мишахответ, вероятно, более читабельный.

0 голосов
/ 10 марта 2014

Вы можете просто использовать поиск, так как поиск по идентификатору принимает конкретный идентификатор (1), список идентификаторов (1, 5, 6) или массив идентификаторов ([5, 6, 10]), см .: http://apidock.com/rails/ActiveRecord/Base/find/class

@companies = Company.find(company_ids)
0 голосов
/ 07 июня 2011

Я думаю, что проблема может быть в том, что у вас есть company_list и company_ids.Я ожидаю, что company_ids в итераторе выдаст что-то вроде:

NameError: undefined local variable or method `company_ids'

Я думаю, что я мог бы написать так:

@task      = Link.find(params[:id])
clients    = Client.where(:task_id => @task.id).select('distinct company_id')
@companies = Company.where(:id => clients.map(&:company_id))
...