@@ -5,8 +5,7 @@ CoderDojoの統計データを年次でダウンロードできる機能を実
55
66### データの取得範囲
77- ** yearパラメータなし(デフォルト)** :
8- - HTML表示: 現在アクティブな道場のみ(既存の動作を維持)
9- - CSV/JSONダウンロード: 全道場(アクティブ + 非アクティブ)
8+ - 全形式(HTML/JSON/CSV): 全道場(アクティブ + 非アクティブ)※既存の動作そのまま
109- ** yearパラメータあり(例: year=2024)** :
1110 - HTML/JSON/CSV すべての形式: その年末時点でアクティブだった道場のみ
1211
@@ -88,19 +87,9 @@ class DojosController < ApplicationController
8887
8988 @page_title = " #{ @selected_year } 年末時点のCoderDojo一覧"
9089 else
91- # yearパラメータなしの場合
92- # HTML表示: 現在のアクティブな道場のみ(既存の実装を維持)
93- # CSV/JSONダウンロード: 全道場(アクティブ + 非アクティブ)
94- if request.format .html?
95- # HTMLの場合は現在アクティブな道場のみ
96- dojos_scope = Dojo .active
97- else
98- # CSV/JSONの場合は全道場(非アクティブも含む)
99- dojos_scope = Dojo .all
100- end
101-
90+ # yearパラメータなしの場合(既存の実装そのまま)
10291 @dojos = []
103- dojos_scope .includes(:prefecture ).order(order: :asc ).each do |dojo |
92+ Dojo .includes(:prefecture ).order(order: :asc ).all .each do |dojo |
10493 @dojos << {
10594 id: dojo.id,
10695 url: dojo.url,
@@ -120,88 +109,13 @@ class DojosController < ApplicationController
120109 respond_to do |format |
121110 format .html { render :index } # => app/views/dojos/index.html.erb
122111 format .json { render json: @dojos }
123- format .csv { send_data render_to_string, type: :csv }
112+ format .csv { send_data render_to_string, type: :csv } # 新規追加
124113 end
125114 end
126115
127116 def show
128117 # 既存の実装のまま
129118 end
130-
131- private
132-
133- def render_yearly_stats
134- @period_start = 2012
135- @period_end = Date .current.year
136-
137- # yearパラメータが指定されている場合(整数のみ許可)
138- if @selected_year # 既にindexアクションで設定済み
139- period = Time .zone.local(@selected_year ).beginning_of_year..Time .zone.local(@selected_year ).end_of_year
140- @stat = Stat .new (period)
141- @yearly_data = prepare_single_year_data(@stat , @selected_year )
142- filename_suffix = @selected_year .to_s
143- else
144- # yearパラメータなし = 全年次データ
145- period = Time .zone.local(@period_start ).beginning_of_year..Time .zone.local(@period_end ).end_of_year
146- @stat = Stat .new (period)
147- @yearly_data = prepare_all_years_data(@stat )
148- filename_suffix = ' all'
149- end
150-
151- # CSVまたはJSONとして返す
152- respond_to do |format |
153- format .csv do
154- send_data render_to_string(template: ' dojos/yearly_stats' ),
155- type: :csv ,
156- filename: " coderdojo_stats_#{ filename_suffix } _#{ Date .current.strftime(' %Y%m%d' )} .csv"
157- end
158- format .json { render json: @yearly_data }
159- end
160- end
161-
162- def prepare_all_years_data (stat )
163- active_dojos = stat.annual_dojos_with_historical_data
164- new_dojos = stat.annual_new_dojos_count
165-
166- # 年ごとのデータを整形
167- years = (@period_start ..@period_end ).map(& :to_s )
168- years.map do |year |
169- prev_year = (year.to_i - 1 ).to_s
170- {
171- year: year,
172- active_dojos_at_year_end: active_dojos[year] || 0 ,
173- new_dojos: new_dojos[year] || 0 ,
174- inactivated_dojos: calculate_inactivated_count(year),
175- cumulative_total: active_dojos[year] || 0 ,
176- net_change: prev_year && active_dojos[prev_year] ?
177- (active_dojos[year] || 0 ) - active_dojos[prev_year] :
178- (active_dojos[year] || 0 )
179- }
180- end
181- end
182-
183- def prepare_single_year_data (stat , year )
184- # 特定年のアクティブな道場リストを返す
185- end_of_year = Time .zone.local(year).end_of_year
186- dojos = Dojo .active_at(end_of_year).includes(:prefecture )
187-
188- dojos.map do |dojo |
189- {
190- id: dojo.id,
191- name: dojo.name,
192- prefecture: dojo.prefecture.name,
193- url: dojo.url,
194- created_at: dojo.created_at.strftime(' %Y-%m-%d' ),
195- is_active_at_year_end: dojo.active_at?(end_of_year)
196- }
197- end
198- end
199-
200- def calculate_inactivated_count (year )
201- start_of_year = Time .zone.local(year.to_i).beginning_of_year
202- end_of_year = Time .zone.local(year.to_i).end_of_year
203- Dojo .where(inactivated_at: start_of_year..end_of_year).sum(:counter )
204- end
205119end
206120```
207121
@@ -382,10 +296,15 @@ RSpec.describe DojosController, type: :controller do
382296 expect(csv[0 ]).to eq([' 年' , ' 年末アクティブ道場数' , ' 新規開設数' , ' 非アクティブ化数' , ' 累積合計' , ' 純増減' ])
383297 end
384298
385- it ' yearパラメータなしの場合は非アクティブな道場も含む(CSV/JSON )' do
299+ it ' yearパラメータなしの場合は非アクティブな道場も含む(全形式 )' do
386300 active_dojo = create(:dojo , is_active: true )
387301 inactive_dojo = create(:dojo , is_active: false , inactivated_at: ' 2021-03-01' )
388302
303+ # HTML形式: 全道場を含む
304+ get :index , format: :html
305+ expect(assigns(:dojos ).map { |d | d[:id ] }).to include (active_dojo.id)
306+ expect(assigns(:dojos ).map { |d | d[:id ] }).to include (inactive_dojo.id)
307+
389308 # JSON形式: 全道場を含む
390309 get :index , format: :json
391310 json_response = JSON .parse(response.body)
@@ -399,11 +318,6 @@ RSpec.describe DojosController, type: :controller do
399318 csv_ids = csv.map { |row | row[' ID' ].to_i }
400319 expect(csv_ids).to include (active_dojo.id)
401320 expect(csv_ids).to include (inactive_dojo.id)
402-
403- # HTML形式: アクティブな道場のみ(既存の動作を維持)
404- get :index , format: :html
405- expect(assigns(:dojos ).map { |d | d[:id ] }).to include (active_dojo.id)
406- expect(assigns(:dojos ).map { |d | d[:id ] }).not_to include (inactive_dojo.id)
407321 end
408322 end
409323
0 commit comments