在Rails中按虚拟属性排序

时间:2013-07-24 15:16:50

标签: sql ruby ruby-on-rails-3 postgresql activerecord

我正在开发Rails 3.2.8 我想将此排序转换为Rails范围。

class Doc < ActiveRecord::Base
   has_many :denotations

   def same_sourceid_denotations_count
      denotation_doc_ids = Doc.where(:sourceid => self.sourceid).collect{|doc| doc.id}
      Denotation.select('doc_id').where('doc_id IN (?)', denotation_doc_ids).size
   end
end

class Denotation < ActiveRecord::Base
   belongs_to :doc
end

ans排序如下

 @docs = docs.sort{|a, b| b.same_sourceid_relations_count <=> a.same_sourceid_relations_count}

我在下面写了范围,但是没有用。

scope :same_sourceid_docs_denotations_count
  select('docs.*, docs.sourceid = docs.sourceid AS same_sourceid_doc_ids, COUNT(denotations.doc_id IN (same_sourceid_doc_ids)) AS same_sourceid_docs_denotations_count')
  .group('docs.id')
  .order('same_sourceid_docs_denotations_count DESC')

出错了。

PG::Error: ERROR:  missing FROM-clause entry for table "denotations"
LINE 1: ...d = docs.sourceid AS same_sourceid_doc_ids, COUNT(denotation...
                                                         ^
: SELECT  docs.*, docs.sourceid = docs.sourceid AS same_sourceid_doc_ids, COUNT(denotations.doc_id IN (same_sourceid_doc_ids)) AS same_sourceid_docs_denotations_count FROM "docs"  WHERE "docs"."sourcedb" = 'PubMed' GROUP BY docs.id ORDER BY same_sourceid_docs_denotations_count DESC LIMIT 10 OFFSET 0
      .group('docs.id')
      .order('same_sourceid_docs_denotations_count DESC')

此排序步骤如下

  • 查找具有相同sourceid的所有文档并获取这些ID。
  • 计算上述ID中包含doc_id的标记。
  • 按上述指示数对文档进行排序。

    &lt; Doc id:1,sourceid:111&gt;
    &lt; Doc id:2,sourceid:111&gt;
    &lt; Denotation id:1,doc_id:1&gt;
    &lt; Denotation id:2,doc_id:2&gt;
    &lt; Denotation id:3,doc_id:2&gt;
    =&GT;与sourceid 111相关的指示数应为3

    &lt; Doc id:3,sourceid:222&gt;
    &lt; Denotation id:4,doc_id:3&gt;
    =&GT;与sourceid 222相关的标记数应为1

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

看起来你错过了一个JOIN子句来引入denotations表。尝试这样的事情(注意使用joins(...)):

scope :same_sourceid_docs_denotations_count,
  select("docs.*, count(denotations.id) AS denotations_count")
  .joins("INNER JOIN denotations ON denotations.sourceid = docs.sourceid")
  .group("docs.id")
  .order("denotations_count DESC")

ActiveRecord Query Interface指南还提供了有关如何使用joins(...)的详细信息。