Rails:构建涉及多态关联和STI的查询

时间:2011-07-05 12:23:56

标签: ruby-on-rails ruby polymorphic-associations eager-loading single-table-inheritance

我正在尝试查找有关照片的10条最新评论,因此我可以将它们集成到我的Rails 3.0.3应用程序的活动源中。

我有一个 Photo 模型,它继承了使用单表继承的上传模型:

class Upload < ActiveRecord::Base
    ...
end

class Photo < Upload
    has_many :comments, :as => :commentable
    ...
end

评论模型中描述了多态关联可评论

class Comment < ActiveRecord::Base
    belongs_to :commentable, :polymorphic => true
end

到目前为止这么好,对吗?当我尝试构造查询时出现问题。经过一些试验和错误,我想出了这个代码,它位于Photo模型中:

def self.latest_comments(count = 10)
    Comment.where(:commentable_type => "Upload")\
       .joins("INNER JOIN uploads ON comments.commentable_id = uploads.id")\
       .where("uploads.type" => "Photo").order("comments.created_at DESC").limit(count)
end

这段代码适用于我的SQLite开发机器,但是我必须做一些修改才能让它在使用PostgreSQL的生产服务器上运行。上面的查询化身尚未在生产服务器上进行过测试,但我一直在寻找一种更简洁的结构化查询方式,因为上面的感觉不是很强大,也不是很“Railsy”。 / p>

我想要的是能够说

Comment.joins(:commentable => :photo)

...但这会引发异常,大概是因为Rails不知道如何进行连接:

  

ActiveRecord :: EagerLoadPolymorphicError:无法急切加载多态关联:commentable

我遇到了post on StackOverflow,它描述了一种查询多态关联的不同方式。我能够根据这篇文章提出以下代码:

Comment.find_all_by_commentable_type("Upload", :include => :commentable,
        :order => "created_at DESC", :limit => 10)

但是,这对STI不起作用:由于Photo继承自Upload,我无法直接获取与照片相关的注释 - 只有从Upload继承的所有类的注释。

我看过很多其他与多态性或STI有关的帖子,但是没有一个与我正在寻找的方式结合起来。我可以对初始查询进行讨论,但有没有人对构建涉及多态 STI的查询的其他方法有任何想法?

修改:我在这里发现了another question和我的一样。不幸的是,最佳答案并未提供我正在寻找的解决方案。如果我将它应用于我的问题,我会将has_many :comments关联从Photo模型移动到Upload模型,并将一些代码添加到Comment类以确定正确的commentable的等级。这并不理想,因为它打破了建模,因为任何上传的子类都会有注释。必须有更好的方法......?

1 个答案:

答案 0 :(得分:1)

您正在提供关于Upload类的评论的关联。继承自Upload的Photo将通过继承进行此关联。由于comments方法在Upload实例和Photo实例上都可用,因此您可以编写以下方法来检索注释:

# app/models/upload.rb

def latest_comments(count=10)
  self.comments.order("created_at DESC").limit(count)
end

当使用上传实例时,这将使用“上传”类型加入评论表,并且在使用该类的实例时,它将使用“照片”类型加入。在通过评论关联时,Rails将使用类名自动处理与评论表的连接。