我正在使用Rails 3,我需要做一个选择,其中记录的主键是在结果先前的选择中。您可以使用IN直接使用SQL来轻松完成此操作。这是我做了我需要的明显不正确的方法。 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)
答案 0 :(得分:38)
正如其他人所说,在这种情况下我会使用join。使用“in”的语法也很简单,例如。
company_ids = [1,2,3,4]
@companies = Company.where("id in (?)", company_ids)
<强>更新强>
实际上它比现在更简单(我认为rails 3+),你可以做到
company_ids = [1,2,3,4]
@companies = Company.where(id: company_ids)
答案 1 :(得分:6)
这不回答您关于“使用where子句选择IN”的问题,但我认为您的整个脚本可以使用joins
在一行中重写。这应该与上面的代码段相同:
@companies = Company.joins(:clients).where(:clients => {:task_id => params[:id]})
答案 2 :(得分:1)
我相信这会满足你的要求:
@task = Link.find(params[:id])
@companies = Company.where(:id => Client.where(:task_id => @task.id).select('distinct company_id').map(&:company_id))
您可以通过在控制台的末尾添加.to_sql来查看sql。
mischa的答案中的连接语法可能更具可读性。
答案 3 :(得分:0)
我认为问题可能是你有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))
答案 4 :(得分:0)
你可以简单地使用find,因为id接受一个特定的id(1),一个id列表(1,5,6)或一个id数组([5,6,10]),参见: http://apidock.com/rails/ActiveRecord/Base/find/class
@companies = Company.find(company_ids)