有没有模型分析宝石?

时间:2012-06-28 18:22:50

标签: ruby-on-rails gem

我正在努力允许客户在一段时间内查看每天,每周,每月的分析,按小时,天或月等分组......所有这些都基于created_at属性。

那里有没有宝石可以做到这一点?类似的东西:

Posts.analytics(:by => :day, :period => :this_week, :column => :created_at)

会回来:

{
'2012-06-19' => 14,
'2012-06-20' => 0, // Empty rows padding support*
'2012-06-21' => 3
}

我正试图从头开始,但如果有一个宝石可以完成这项工作,那似乎是很多不必要的工作。

更新

我尝试制作一个包含在所有模型中的分析模块,以便轻松生成分析,但它真的不可靠,Sometimed我得到的日子比我需要的多,而且非常混乱,任何人都可以合作并重写/改进:

# Usage:
# include Analytics::Timeline
# Model.timeline(:period => :last_24_hours, :time_by => :hour)

module Analytics
  module Timeline
    def self.included(base)
      base.class_eval {

        def self.timeline(*filters)
          filters = filters[0]
          period  = filters[:period] || :this_week
          time_by = filters[:time_by] || :days
          date_column = filters[:date_column] || :created_at

          # Named periods conventions
          period_range = case period
            when :last_12_hours
              [Time.now-12.hours, Time.now]
            when :last_24_hours
              [Time.now-24.hours, Time.now]
            when :last_7_days
              [Time.now-7.days, Time.now]
            when :last_30_days
              [Time.now-30.days, Time.now]
            when :this_week
              [Time.now.beginning_of_week, Time.now.end_of_week]
            when :past_week
              [(Time.now - 1.week).beginning_of_week, (Time.now - 1.week).end_of_week]
            when :this_month
              [Time.now.beginning_of_month, Time.now.end_of_month]
            when :past_month
              [(Time.now-1.month).beginning_of_month, (Time.now - 1.month).end_of_month]
            when :this_year
              [Time.now.beginning_of_year, Time.now.end_of_year]
            end
          period_range = period if period.kind_of?(Array)
          period_range = [period, Time.now] if period.is_a?(String)

          # determine the SQL group method
          group_column = case time_by
            when :months
              time_suffix = "-01 00:00:00"
              records = where("#{table_name}.#{date_column} > ? AND #{table_name}.#{date_column} <= ?", period_range[0].to_date, period_range[1].to_date)
              "DATE_FORMAT(#{table_name}.#{date_column.to_s}, '%Y-%m')"
            when :days
              time_suffix = " 00:00:00"
              records = where("#{table_name}.#{date_column} > ? AND #{table_name}.#{date_column} <= ?", period_range[0].to_date, period_range[1].to_date)
              "DATE(#{table_name}.#{date_column.to_s})"
            when :hours
              time_suffix = ":00:00"
              records = where("#{table_name}.#{date_column} > ? AND #{table_name}.#{date_column} <= ?", period_range[0], period_range[1])
              "DATE_FORMAT(#{table_name}.#{date_column.to_s}, '%Y-%m-%d %H')"
            when :minutes
              time_suffix = ":00"
              records = where("#{table_name}.#{date_column} > ? AND #{table_name}.#{date_column} <= ?", period_range[0], period_range[1])
              "DATE_FORMAT(#{table_name}.#{date_column.to_s}, '%Y-%m-%d %H:%M')"
            end

          # Get counts per cycle
          records = records.group(group_column).select("*, count(*) AS series_count, #{group_column} AS series_time")
          series = {}

          # Generate placeholder series
          time_table = { :days => 60*60*24, :hours => 60*60, :minutes => 60, :seconds => 0 }

          if time_by == :months
            ticks = 12 * (period_range[1].year - period_range[0].year) + (period_range[1].month + 1) - period_range[0].month
          else
            ticks = (period_range[1] - period_range[0] + 1) / time_table[time_by]
          end

          ticks.to_i.times do |i|
            time = period_range[1]-i.send(time_by)
            time = case time_by
            when :minutes
              time.change(:sec => 0)
            when :hours
              time.change(:min => 0)
            when :days
              time.change(:hour => 0)
            when :months
              time.change(:day => 1, :hour => 0)
            end

            series[time.to_s(:db)] = 0
          end

          # Merge real counts with placeholder series
          to_merge = {}
          records.each do |r|
            to_merge[r.series_time.to_s+time_suffix] = r.series_count
          end

          series.merge!(to_merge)
        end

      }
    end
  end
end

1 个答案:

答案 0 :(得分:2)

ActiveRecord statistics gem似乎对您非常有用。

如果统计信息宝石没有帮助,admin_data gem内置了一些分析。请查看the demo。使用整个管理系统可能过度,但您至少可以尝试浏览源代码以模拟分析功能。