Skip to content

Commit c038497

Browse files
committed
feat: Move /events/latest to /dojos/activity following Rails Way
- RESTfulなURLパターンに従い、道場の活動状況を /dojos/activity に移動 - 情報アーキテクチャの改善(道場関連は/dojos配下に統一) - 旧URL (/events/latest) から新URLへの301リダイレクトを設定 - テストを追加(最小限の実装、YAGNI原則に従う)
1 parent 2bc0d97 commit c038497

File tree

4 files changed

+190
-3
lines changed

4 files changed

+190
-3
lines changed

app/controllers/dojos_controller.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,39 @@ def show
105105
format.csv { send_data render_to_string, type: :csv }
106106
end
107107
end
108+
109+
# GET /dojos/activity
110+
# 道場の活動状況を表示(旧 /events/latest から移行)
111+
def activity
112+
@latest_event_by_dojos = []
113+
Dojo.active.each do |dojo|
114+
link_in_note = dojo.note.match(URI.regexp)
115+
date_in_note = dojo.note.match(/(\d{4}-\d{1,2}-\d{1,2})/) # YYYY-MM-DD
116+
last_session_link = link_in_note.nil? ? dojo_path(dojo.id) : link_in_note.to_s
117+
last_session_date = date_in_note.nil? ? dojo.created_at : Time.zone.parse(date_in_note.to_s)
118+
119+
latest_event = dojo.event_histories.newest.first
120+
latest_event_at = latest_event.nil? ? Time.zone.parse('2000-01-23') : latest_event.evented_at
121+
@latest_event_by_dojos << {
122+
id: dojo.id,
123+
name: dojo.name,
124+
note: dojo.note,
125+
url: dojo.url,
126+
has_event_histories: latest_event.nil?,
127+
128+
# 過去のイベント開催日と note 内の日付を比較し、新しい方の日付を表示
129+
event_at: (latest_event_at < last_session_date) ?
130+
last_session_date.strftime("%Y-%m-%d") :
131+
latest_event.evented_at.strftime("%Y-%m-%d"),
132+
133+
# 過去のイベント開催日と note 内の日付を比較し、新しい方のリンクを表示
134+
event_url: (latest_event_at < last_session_date) ?
135+
last_session_link :
136+
latest_event.event_url
137+
}
138+
end
139+
140+
# Sort by older events first && older Dojo ID first if same event date.
141+
@latest_event_by_dojos.sort_by!{ |dojo| [dojo[:event_at], dojo[:id]] }
142+
end
108143
end

app/views/dojos/activity.html.erb

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<% provide(:title, '道場活動状況') %>
2+
<% provide(:desc, '各道場の最新の活動状況を確認できます。') %>
3+
<% provide(:url, activity_dojos_url) %>
4+
<% provide(:meta_image, '/img/ogp-events.jpeg') %>
5+
6+
<section class="cover">
7+
<%= lazy_image_tag('/events_cover.jpg', alt: 'Cover Photo on Upcoming Events', min: true) %>
8+
</section>
9+
10+
<section id="events" class="text-center" style="margin-bottom: 100px;">
11+
<br />
12+
<h1>☯️ 道場活動状況</h1>
13+
<br />
14+
<p style="margin: 0 0px 40px 10px; line-height: 1.5em;">
15+
各道場の最新の活動状況を確認できます。
16+
<a href="/signup#terms-of-use">Active/Inactive</a>
17+
の判断などにもご活用ください。
18+
<br>
19+
<div class='form__terms list'>
20+
<ul style='list-style-type: "\2713\0020"; font-size: smaller;'>
21+
<li><%= link_to '近日開催', events_path %>のデータは含まず、<%= link_to '過去開催', stats_path %>のデータを使っています。</li>
22+
<li>開催データは <a href='https://doorkeeper.jp/'>Doorkeeper</a><a href='http://connpass.com/'>connpass</a> にのみ対応しています。</li>
23+
<li>上記以外でイベント管理している場合は掲載日を表示しています。</li>
24+
</ul>
25+
</div>
26+
</p>
27+
28+
<style type="text/css">
29+
/* URL 用のセルにクラスを付けておく想定 */
30+
table { table-layout: auto; }
31+
td {
32+
padding: 1px 10px 1px 10px;
33+
text-align: right;
34+
font-size: smaller;
35+
}
36+
span.expired {
37+
a {
38+
color: red;
39+
background-color: #ffe5e5; /* 薄い赤背景 */
40+
}
41+
}
42+
td.url-cell {
43+
white-space: normal; /* 改行を許可 */
44+
word-wrap: break-word; /* 古めのブラウザ向け */
45+
overflow-wrap: break-word; /* 新しめのブラウザ向け */
46+
word-break: break-all; /* 英数字が続く場合の保険 (必要に応じて) */
47+
text-align: left;
48+
}
49+
th {
50+
padding: 10px;
51+
text-align: center;
52+
}
53+
</style>
54+
55+
<div style="margin-top: 20px;" align="center">
56+
<table border="1">
57+
<tr>
58+
<th>
59+
<small>☯️ 道場名</small>
60+
</th>
61+
<th>
62+
<small><small>
63+
🗓 直近の開催日または掲載日
64+
</small></small>
65+
</th>
66+
<th>
67+
<small>📝 ノート</small>
68+
</th>
69+
</tr>
70+
<% @latest_event_by_dojos.each do |dojo| %>
71+
<tr>
72+
<td>
73+
<small>
74+
<a href="<%= dojo[:url] %>"><%= dojo[:name] %></a>
75+
</small>
76+
</td>
77+
<td>
78+
<small>
79+
<% if dojo[:has_event_histories] %>
80+
<!-- 過去1年間イベント開催していない Dojo で、"Active" マークが無い場合はハイライトする -->
81+
<span class=<%= 'expired' if dojo[:event_at] <= Time.current.prev_year && !dojo[:note].include?('Active') %>>
82+
<%= link_to dojo[:event_at], dojo[:event_url] %>
83+
</span>
84+
<% else %>
85+
<!-- 別サービスでイベント管理している Dojo で、"Active" マークが無い場合はハイライトする -->
86+
<!-- 別サービスでイベント管理している Dojo なら、note にある日付とリンクがあれば表示する -->
87+
<span class=<%= 'expired' if dojo[:event_at] <= Time.current.prev_year && !dojo[:note].include?('Active') %>>
88+
<%= link_to dojo[:event_at], dojo[:event_url] %>
89+
</span>
90+
<% end %>
91+
</small>
92+
</td>
93+
<td class="url-cell">
94+
<small>
95+
<span title="<%= dojo[:note] %>"><%= raw Addressable::URI.unescape(Rinku.auto_link(dojo[:note])) %></span>
96+
</small>
97+
</td>
98+
</tr>
99+
<% end %>
100+
</table>
101+
</div>
102+
103+
<p>
104+
<pre style='white-space: pre-wrap; margin-top: 60px; color: #505050;'>本ページにある開催日は <br class='ignore-pc'><a href='https://doorkeeper.jp/'>Doorkeeper</a><a href='http://connpass.com/'>connpass</a> にのみ対応しています。</pre>
105+
</p>
106+
<div style='margin-top: 30px;'><a href='#top'>&uarr; 上に戻る</a></div>
107+
</section>

config/routes.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@
6464
get "/kata" => "docs#kata"
6565
#get "/debug/kata" => "docs#kata"
6666

67-
resources :dojos, only: %i(index show) # GET /dojos.json returns dojo data as JSON
67+
resources :dojos, only: %i(index show) do # GET /dojos.json returns dojo data as JSON
68+
collection do
69+
get :activity # GET /dojos/activity - 道場活動状況(旧 /events/latest)
70+
end
71+
end
6872
resources :docs, only: %i(index show)
6973
resources :podcasts, only: %i(index show)
7074
resources :spaces, only: %i(index)
@@ -84,9 +88,11 @@
8488
#resources :stats, only: %i(show)
8589
#resources :pokemons, only: %i(index create)
8690

87-
# Upcoming Events & Latest Events
91+
# Upcoming Events
8892
get '/events' => 'events#index'
89-
get '/events/latest' => 'events#latest'
93+
94+
# Legacy redirect: /events/latest moved to /dojos/activity
95+
get '/events/latest', to: redirect('/dojos/activity')
9096

9197
# Redirects
9298
get "/releases/2016/12/12/new-backend", to: redirect('/docs/post-backend-update-history')

spec/requests/dojos_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,43 @@
318318
end
319319
end
320320
end
321+
322+
describe "GET /dojos/activity" do
323+
before do
324+
# アクティブな道場を作成
325+
@active_dojo = create(:dojo,
326+
name: "Active Dojo",
327+
created_at: 1.week.ago,
328+
inactivated_at: nil
329+
)
330+
331+
# 非アクティブな道場を作成
332+
@inactive_dojo = create(:dojo,
333+
name: "Inactive Dojo",
334+
created_at: 2.years.ago,
335+
inactivated_at: 1.year.ago
336+
)
337+
end
338+
339+
it "returns http success" do
340+
get activity_dojos_path
341+
expect(response).to have_http_status(:success)
342+
end
343+
344+
it "displays the activity status page" do
345+
get activity_dojos_path
346+
expect(response.body).to include("道場活動状況")
347+
end
348+
349+
it "includes only active dojos" do
350+
get activity_dojos_path
351+
expect(response.body).to include(@active_dojo.name)
352+
expect(response.body).not_to include(@inactive_dojo.name)
353+
end
354+
355+
it "redirects from old URL /events/latest" do
356+
get "/events/latest"
357+
expect(response).to redirect_to(activity_dojos_path)
358+
end
359+
end
321360
end

0 commit comments

Comments
 (0)