Как разделить несколько соединений и условий - PullRequest
1 голос
/ 22 марта 2012

Я хочу отобразить список всех проектов, где находится проект

  • имеет одну или несколько задач

    И

  • имеет одного или нескольких клиентов ИЛИ имеет флаг 'can_have_clients = 0'

    И

  • 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)

Можно ли разделить больше (особенно последний, где / ИЛИ), и похоже ли это на путь с рельсами?

# 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 ]

2 голосов
/ 22 марта 2012

Попробуйте это:

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 голос
/ 22 марта 2012

Я думаю, что вы можете использовать named_scope здесь, чтобы оптимизировать ваш запрос в формате рельсов.

А для тисков производительности вы можете сделать запрос вроде:

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)

потому что он слишком дорог, чем существует, отметьте его .

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