0

ここには、いいね、コメント、コンテンツ、ビューに関する統計を収集する必要があるクラスがあります

class UsersActivityTable

  def initialize(user_ids, content_ids, start_date, end_date)
    @user_ids, @content_ids, @start_date, @end_date = user_ids, content_ids,  start_date,  end_date
  end

  def rows
    @rows ||= @user_ids.map do |user_id|
                OpenStruct.new( :full_name => sum_users(user_id),
                                :contributed => sum_contributed(user_id),
                                :interacted => sum_interacted(user_id)
                              )
               end
  end

  private

  def sum_users(user_id)
    @sum_users ||= Hash[ User.value_of(:id, :first_name, :last_name).map{|usr| [usr[0], "#{usr[1]} #{usr[2]}"] } ]
    @sum_users[user_id]
  end

  def sum_contributed(user_id)
    @sum_contributed ||= Content.where(:user_id => @user_ids, :id => @content_ids)
                                .where('date(created_at) between ? and ? ', @start_date, @end_date)
                                .group(:user_id)
                                .count
    @sum_contributed[user_id].to_i
  end

  def sum_interacted(user_id)
    sum_comments(user_id).to_i + sum_views(user_id).to_i + sum_likes(user_id).to_i
  end

  def sum_comments(user_id)
    @sum_comments ||= Comment.where(:user_id => @user_ids, :content_id => @content_ids)
                             .where('date(created_at) between ? and ? ', @start_date, @end_date)
                             .group(:user_id)
                             .count
    @sum_comments[user_id]
  end

  def sum_likes(user_id)
    @sum_likes ||= Like.where(:user_id => @user_ids, :content_id => @content_ids)
                       .where('date(created_at) between ? and ? ', @start_date, @end_date)
                       .group(:user_id)
                       .count
    @sum_likes[user_id]
  end

  def sum_views(user_id)
    @sum_views ||= View.where(:viewable_type => 'Content', :user_id => @user_ids, :viewable_id => @content_ids)
                       .where('date(created_at) between ? and ? ', @start_date, @end_date)
                       .group(:user_id)
                       .count
    @sum_views[user_id]
  end
end

ご覧のとおり、いくつかの重複があります。

.where('date(created_at) between ? and ? ', @start_date, @end_date)
.group(:user_id)
.count

エンティティごとに実行します。条件ラムダなどを適用する方法はありますか?

私が可能だと思うのは、コレクションインスタンスでメソッドを定義して呼び出すことです:

# pseudo code
group_results = lambda{|el| el.where('date(created_at) between ? and ? ', @start_date, @end_date)
                             .group(:user_id)
                             .count }
Content.where(...).tap{|collection| collection.defune_method .... }.group_results
4

1 に答える 1

1

重要な統計の場合、必要なすべてを返す 1 つの find_by_sql の方が効率的であり、複雑な Rubyよりも髪がはっきりしている可能性があります。

もちろんYMMV:)

于 2012-10-01T13:51:52.790 に答える