2

私は、クライアントが日、週、月ごと、一定期間、時間、日、月などでグループ化された分析を表示できるようにすることに取り組んでいます...それらはすべて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
}

ゼロから作ろうとしているのですが、すでにgemがあると余計な作業が多くなりそうです。

アップデート

簡単に分析を生成できるように、すべてのモデルに含まれる分析モジュールを作成しようとしました. しかし、それは本当に信頼できません. 必要以上に日数がかかることがあり、本当に面倒です.

# 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
4

1 に答える 1

2

ActiveRecord の統計ジェムは、あなたにとって非常に役立つようです。

統計ジェムが役に立たない場合は、admin_data ジェムにいくつかの分析機能が組み込まれています。デモをご覧ください。管理システム全体を使用するのはやり過ぎかもしれませんが、少なくともソースを参照して分析機能を模倣することはできます。

于 2012-07-01T00:59:01.527 に答える