Paginating通过计算列连接结果

时间:2013-08-12 14:00:46

标签: ruby-on-rails-3 postgresql will-paginate calculated-columns rails-postgresql

我们正在为客户计算统计数据。计算每个SpecialtyLevel的统计信息,每个统计信息可以有多个错误标记(不要与验证错误混淆)。以下是关系(以下所有类都嵌套在多个模块中,为简单起见,我在此省略了这些:)

  class SpecialtyLevel < ActiveRecord::Base
    has_many :stats,
      :class_name =>"Specialties::Aggregate::Stat",
      :foreign_key => "specialty_level_id"

    .......
  end

      class Stat < Surveys::Stat

        belongs_to :specialty_level

        has_many :stat_flags,
          :class_name => "Surveys::PhysicianCompensation::Stats::Specialties::Aggregate::StatFlag",
          :foreign_key => "stat_id"

        ......
      end

      class StatFlag < Surveys::Stats::StatFlag
        belongs_to :stat, :class_name => "Surveys::PhysicianCompensation::Stats::Specialties::Aggregate::Stat"

        ......
      end

在视图中,我们为每个SpecialtyLevel显示一行,每个Stat显示一列,另一列指示SpecialtyLevel是否有任何错误标记。客户端希望能够通过错误标志的数量对表进行排序。为实现这一目标,我在SpecialtyLevel类中创建了一个范围:

    scope :with_flag_counts,
      select("#{self.columns_with_table_name.join(', ')}, count(stat_flags.id) as stat_flags_count").
      joins("INNER JOIN #{Specialties::Aggregate::Stat.table_name} stats on stats.specialty_level_id = #{self.table_name}.id
             LEFT OUTER JOIN #{Specialties::Aggregate::StatFlag.table_name} stat_flags on stat_flags.stat_id = stats.id"
      ).
      group(self.columns_with_table_name.join(', '))

现在,从数据库返回的每一行都有一个stat_flags_count字段,我可以按其排序。这工作正常,但当我尝试使用此代码进行分页时遇到问题:

  def always_show_results_count_will_paginate objects, options = {}
    if objects.total_entries <= objects.per_page
      content_tag(:div, content_tag(:span, "Showing 0-#{objects.total_entries} of #{objects.total_entries}", :class => 'info-text'))
    else
      sc_will_paginate objects, options = {}
    end
  end

出于某种原因,objects.total_entries返回1.似乎我的范围内的某些内容导致Rails使用它给我的结果集做了一些非常时髦的东西。

问题是,我可以使用另一种方法来返回正确的值吗?或者有没有办法可以调整我的范围以防止这种干扰发生?

2 个答案:

答案 0 :(得分:1)

group声明让我怀疑。您可能需要启动调试器并逐步执行代码并查看实际返回的内容。

您是否有特殊原因使用范围而不只是SpecialtyLevel模型上的属性?您是否只能在def上添加SpecialtyLevel作为“虚拟属性”,只返回length列表的StatFlag

答案 1 :(得分:0)

这里的答案是单独计算total_entries并将其传递到paginate方法,例如:

count = SpecialtyLevel.for_participant(@participant).count
@models = SpecialtyLevel.
  with_flag_counts.
  for_participant(@participant).
  paginate(:per_page => 10, :page => page, :total_entries => count)