Запрос полиморфной ассоциации

У меня такая полиморфная ассоциация -

class Image < ActiveRecord::Base
  has_one :approval, :as => :approvable
end

class Page < ActiveRecord::Base
  has_one :approval, :as => :approvable
end

class Site < ActiveRecord::Base
  has_one :approval, :as => :approvable
end

class Approval < ActiveRecord::Base
  belongs_to :approvable, :polymorphic => true
end

Мне нужно найти утверждения, где approval.apporvable.deleted = false

Я пробовал что-то вроде этого -

@approvals = Approval.find(:all, 
   :include => [:approvable], 
   :conditions => [":approvable.deleted = ?", false ])

Это дает ошибку «Не удается загрузить полиморфную ассоциацию: одобрено».

Как можно правильно задать условие, чтобы я получил набор результатов с утверждениями, чей утвержденный элемент не удален?

Спасибо за любую помощь заранее


person dewdrops    schedule 23.07.2010    source источник
comment
Вместо N+1 это можно было бы сделать с помощью 4 массовых запросов, по одному для каждого класса ассоциации, плюс первоначальный предварительный просмотр всех ассоциаций. Структура подготовительных данных будет представлять собой хэш, отображающий каждый класс ассоциации на [source_id, Association_id].   -  person mahemoff    schedule 21.04.2015


Ответы (4)


Это невозможно, поскольку все «одобряемые» находятся в разных таблицах. Вместо этого вам придется получить все утверждения, а затем использовать обычные методы массива.

@approvals = Approval.all.select { |approval| !approval.approvable.deleted? }
person Daniel Abrahamsson    schedule 23.07.2010

Что вы спрашиваете, с точки зрения SQL, проецирует данные из разных таблиц для разных строк в наборе результатов. Насколько мне известно, это невозможно.

Итак, вам придется довольствоваться:

@approvals = Approval.all.reject{|a| a.approvable.deleted? }
# I assume you have a deleted? method in all the approvables
person Swanand    schedule 23.07.2010

Я бы порекомендовал любой из уже представленных здесь ответов (это одно и то же), но я бы также рекомендовал поместить этот удаленный флаг в модель утверждения, если вы действительно хотите сделать все это в одном запросе.

С полиморфными отношениями рельсы могут использовать нетерпеливую выборку полигонов, но вы не можете присоединиться к ним, потому что, опять же, отношения неизвестны, поэтому запрос на самом деле представляет собой несколько пересекающихся запросов.

Итак, в конце концов, если вам ДЕЙСТВИТЕЛЬНО нужно, загляните в sql и пересеките все возможные соединения, которые вы можете сделать для всех типов одобренных в одном запросе, но вам придется выполнять много соединений вручную. (вручную означает не использовать встроенные механизмы рельсов...)

person Dmitriy Likhten    schedule 23.07.2010

спасибо за ваши ответы, я был уверен, что это невозможно. Мне нужно было еще одно подтверждение, помимо того, что я надеялся на какое-то другое решение, чем зацикливание на наборе результатов, чтобы избежать проблем, связанных с производительностью, позже. вручную. В очередной раз благодарим за помощь!!

M

person dewdrops    schedule 23.07.2010