一応実装の時に考えることは
rangeオブジェクトは
ご存知かもしれませんが,
.2個で等号含む
.3個で不等号のみ
を考え,実際にサーバにどのようなqueryが投げられているか確認すると,無駄を削減できると思います。
また,共通の処理を関数に切り出し,いいかもしれません。私は以下のように特定の月次ではなく任意の区間を指定できるような実装にして汎用性を高くします。
もし月次の定義がずれていた場合は,適宣補完していただけると幸いです。
ruby
1
2def main_action
3 @this_month,@last_month,@before_last_month = fetch_during_month_data
4end
5
6private
7
8def fetch_during_month_data(start_month=Date.today.month-2,end_month=Date.today.month,year=Date.today.year)
9 end_month.downto(start_month).map do |target_month|
10 current_month = Date.new(year,target_month)
11 fetch_monthly_data(current_month...current_month.next_month)
12 end
13end
14
15def fetch_monthly_data(range)
16 User.where(user_id: @user.id, created_at:range).count
17end
もしくはfetch_monthly_data(range)はまとめてしまって
ruby
1
2def main_action
3 @this_month,@last_month,@before_last_month = fetch_during_month_data
4end
5
6private
7
8def fetch_during_month_data(start_month=Date.today.month-2,end_month=Date.today.month,year=Date.today.year)
9 end_month.downto(start_month).map do |target_month|
10 current_month = Date.new(year,target_month)
11 range = current_month...current_month.next_month
12 User.where(user_id: @user.id, created_at:range).count
13 end
14end
15
とします。
追記
上記コードは,年次ごとにはわかりやすいのですが,年をまたげないので年をまたぐ必要がある場合にはfetch_during_month_data
を以下のように修正します。
ruby
1def fetch_during_month_data(end_month=Date.today.month,back_months = 2 ,year=Date.today.year)
2 current_month = Date.new(year,end_month)
3 (0..back_months).map do |back|
4 current_month = current_month.months_ago(back)
5 range = current_month...current_month.next_month
6 User.where(user_id: @user.id, created_at:range).count
7 end
8end
期間指定したい場合は,
ruby
1def main_action
2 @this_month,@last_month,@before_last_month = fetch_during_month_data
3end
4
5private
6
7def fetch_during_month_data(start_month=Date.today.months_ago(2),end_month=Date.today)
8 back_months = (end_month.year - start_month.year)*12 - start_month.month + end_month.month
9 (0..back_months).map do |back|
10 current_month = current_month.months_ago(back)
11 range = current_month...current_month.next_month
12 User.where(user_id: @user.id, created_at:range).count
13 end
14end
15
とすることでできます。