我已经设置了一个模型结构,它允许不同的模型通过has_many ...:through ...关联与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
然后我使用此设置从具有附件的特定资源中检索所有文件,这是一个图像,如下所示:
@resource.files.images
当我检查由此生成的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' )
)
)
如果我只尝试调用@ resource.files,那么条件不会重复。
这当然是按预期工作的,但从查询来看,似乎我做了一些可以改进的事情,我尽可能多地考虑性能。那么为什么会发生这种奇怪的事情呢?我该怎样做才能改善呢?
对于记录,使用了rails 2.3.5和mysql。
我最近做了类似上面描述的设置,唯一的区别是没有多态关联,但是当我查看查询时,仍然重复条件。所以这不是问题的原因。
然后我也尝试从上面描述的named_scope中删除lambda。我意识到这是不必要的,因为我没有提供任何论据。因此范围最终看起来像:
named_scope :images, :include => :attachment, :conditions => "attachments.type = 'AttachmentImage'"
仍然重复...
可能是打开机票的时候了,但我正在考虑很快迁移到Rails 3,所以我想我可以等一下,看看会发生什么。
答案 0 :(得分:1)
请注意,在rails 3.0'named_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