为什么Rails在使用带关联的作用域时会生成重复的SQL条件?

Dan*_*nne 5 sql named-scope ruby-on-rails associations

我已经设置了一个模型结构,允许不同的模型通过has_many ...:through ...关联文件模型,该关联也是多态的,因此文件可以属于许多不同的模型,不同的资源可以有很多文件.

然后,File模型属于Attachment模型,它是实际文件,但我使用File模型来跟踪不同的版本.附件模型知道文件是否是图像.

这是基本的模型结构:

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
Run Code Online (Sandbox Code Playgroud)

然后,我使用此设置从特定资源中检索具有附件的所有文件,该附件是图像,如下所示:

@resource.files.images
Run Code Online (Sandbox Code Playgroud)

当我检查由此生成的SQL查询时,它包含了使用FileAssociation两次加入Resource的条件:

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' )
  )
)
Run Code Online (Sandbox Code Playgroud)

如果我只尝试调用@ resource.files,那么条件不会重复.

这当然是按预期工作的,但从查询来看,似乎我做了一些可以改进的事情,我尽可能多地考虑性能.那么为什么会发生这种奇怪的事情呢?我能做些什么来改进呢?

为了记录,使用rails 2.3.5和mysql.

更新

我最近做了类似上面描述的设置,唯一的区别是没有多态关联,但是当我查看查询时,仍然重复条件.所以这不是问题的原因.

然后我也尝试从上面描述的named_scope中删除lambda.我意识到这是不必要的,因为我没有提供任何论据.所以范围最终看起来像:

  named_scope :images, :include => :attachment, :conditions => "attachments.type = 'AttachmentImage'"
Run Code Online (Sandbox Code Playgroud)

仍然重复......

可能是打开机票的时候了,但我正在考虑很快迁移到Rails 3,所以我想我可以等一下,然后看看会发生什么.

Dav*_*vid 1

请注意,在 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
Run Code Online (Sandbox Code Playgroud)