如何拆分多个连接和条件

时间:2012-03-22 07:21:22

标签: ruby-on-rails ruby-on-rails-3 activerecord associations

我想显示项目的所有项目列表

  • 有一个或多个任务

  • 有一个或多个客户端或者标记'can_have_clients = 0'

    AND

  • current_user已在客户端上分配

我当前的查询有效,但看起来不正确:

Project.where('id IN (SELECT DISTINCT project_id FROM tasks)')
       .where('id IN (SELECT DISTINCT project_id FROM clients WHERE id IN (
                        SELECT DISTINCT resource_id FROM assignments WHERE resource_type="Client" AND user_id=?)) 
               OR can_have_clients = 0', current_user)

是否可以分割更多(特别是最后一个/或者)并且这看起来像是使用rails的方式?

# model
class Project < ActiveRecord::Base
  has_many :tasks
  has_many :clients
  ...
class Task < ActiveRecord::Base
  belongs_to :project
  ...
class Client < ActiveRecord::Base
  has_many :assignments, :as => :resource
  ...

2 个答案:

答案 0 :(得分:2)

试试这个:

Project.joins(:tasks).joins( :clients => :assignments).where(
  :projects    => { :can_have_clients => 0},
  :assignments => { :resource_type => "Client",  :user_id => current_user}
).select("DISTINCT project.*")

如果您想要加载任务和客户端以及分配:

Project.include(:tasks).include( :clients => :assignments).
  where("tasks.id IS NOT NULL AND clients.id IS NOT NULL AND 
    assignments.id IS NOT NULL").
  where(
    :projects    => { :can_have_clients => 0},
    :assignments => { :resource_type => "Client",  :user_id => current_user}
  )

答案 1 :(得分:1)

我认为您可以在此处使用named_scope以rails格式优化您的查询。

对于性能恶习,您可以进行如下查询:

Project.where('exists (SELECT 1 FROM tasks where tasks.project_id=project.id)')
       .where('exists (SELECT 1 FROM clients WHERE exists (
                        SELECT 1 FROM assignments WHERE assignments.resource_id=clients.id AND resource_type="Client" AND user_id=?)) 
               OR can_have_clients = 0', current_user)

因为in的成本太高,check it