Почему Rails генерирует дублированные условия SQL при использовании областей с ассоциациями? - PullRequest
5 голосов
/ 01 декабря 2010

Я настроил структуру модели, которая позволяет различным моделям связываться с моделью Файла через ассоциацию has_many ...: through ..., которая также полиморфна, так что Файл может принадлежать многим различным моделям, и разные Ресурсы могут иметьмного файлов.

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

Вот базовая структура модели:

class Resource < ActiveRecord::Base
  has_many :file_associations, :as => :association
  has_many :files, :through => :file_associations
  ...
end

class FileAssociation < ActiveRecord::Base
  belongs_to :r_file
  belongs_to :association, :polymorphic => true
  ...
end

class File < ActiveRecord::Base
  has_many :file_associations
  belongs_to :attachment

  named_scope :images, lambda { { :include => :attachment,
                                  :conditions => "attachments.type = 'AttachmentImage'" } }
  ...
end

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

@resource.files.images

Когда я проверяю SQL-запрос, сгенерированный из этого, он включил это условие, чтобы дважды связать ресурс с FileAssociation:

SELECT ....
FROM `files`
LEFT OUTER JOIN `attachments` ON `attachments`.id = `files`.attachment_id
INNER JOIN `file_associations` ON `files`.id = `file_associations`.file_id
WHERE
(
  ( `file_associations`.association_id = 1 ) AND
  ( `file_associations`.association_type = 'Resource' )
)
AND
(
  ( attachments.type = 'AttachmentImage' ) AND
  (
    ( `file_associations`.association_id = 1 ) AND
    ( `file_associations`.association_type = 'Resource' )
  )
)

Если я пытаюсь вызвать только @ resource.files, тогда условиене дублируется.

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

Для записи используются рельсы 2.3.5 и mysql.

Обновление

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

Затем я также попытался удалить лямбду из named_scope, описанного выше.Я понял, что это было немного ненужно, поскольку я не приводил никаких аргументов.Таким образом, область действия выглядела так:

  named_scope :images, :include => :attachment, :conditions => "attachments.type = 'AttachmentImage'"

Все еще дублируется ...

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

1 Ответ

1 голос
/ 02 декабря 2010

Обратите внимание, что в rails 3.0 «named_scope» не рекомендуется в пользу просто «scope»

Я не знаю, почему Rails удваивает условие, это может быть ошибка иликрайний случай.

Вы пробовали вторую ассоциацию has_many, что-то вроде этого:

class Resource < ActiveRecord::Base
  has_many :file_associations, :as => :association
  has_many :files, :through => :file_associations
  has_many :images, :through => :file_associations,
                    :source => :file,
                    :include => :attachment,
                    :conditions => "attachments.type = 'AttachmentImage'"
  ...
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...