Skip to content

Commit 89c623d

Browse files
committed
♻️ Fat Helperを避けてNewsモデルにメソッドを移動
- format_news_title → News#formatted_title に移動 - news_link_url → News#link_url に移動 - ApplicationHelperから News 関連のメソッドを削除 - ビューファイルをモデルメソッドを使用するように更新 - テストも適切な場所(spec/models/news_spec.rb)に移動 Single Responsibility Principleに従い、Newsリソースに関連する ロジックはNewsモデルに配置することでコードの保守性を向上
1 parent b9bb70b commit 89c623d

File tree

7 files changed

+73
-69
lines changed

7 files changed

+73
-69
lines changed

app/controllers/news_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class NewsController < ApplicationController
22
def index
3-
@title = 'CoderDojo ニュース'
4-
@desc = 'CoderDojo に関する最新のニュースや<br class="ignore-pc">お知らせをまとめたページです。'
3+
@title = '☯️ CoderDojo ニュース ✉️'
4+
@desc = 'CoderDojo に関するお知らせの一覧ページです。'
55
@url = request.url
66

77
# データベースからニュースデータを取得(最新順)

app/helpers/application_helper.rb

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def prefecture_name_in_english(prefecture_name)
107107
# 都道府県名の英語表記を返す簡易マッピング
108108
# 「都」「府」「県」を除去してから検索
109109
name_without_suffix = prefecture_name.gsub(/[都府県]$/, '')
110-
110+
111111
prefecture_names = {
112112
'北海道' => 'Hokkaido',
113113
'青森' => 'Aomori',
@@ -157,7 +157,7 @@ def prefecture_name_in_english(prefecture_name)
157157
'鹿児島' => 'Kagoshima',
158158
'沖縄' => 'Okinawa'
159159
}
160-
160+
161161
prefecture_names[name_without_suffix] || prefecture_name
162162
end
163163

@@ -208,32 +208,8 @@ def translate_dojo_tag(tag_name)
208208
'HTML' => 'HTML',
209209
'CSS' => 'CSS'
210210
}
211-
212-
tag_translations[tag_name] || tag_name
213-
end
214211

215-
def format_news_title(news)
216-
has_custom_emoji = news.title[0]&.match?(/[\p{Emoji}&&[^0-9#*]]/)
217-
return news.title if has_custom_emoji
218-
219-
# Add preset Emoji to its prefix if news.title does not have Emoji.
220-
emoji = case news.url
221-
when %r{/podcasts/\d+}
222-
'📻'
223-
when %r{prtimes\.jp}
224-
'📢'
225-
else
226-
'📰'
227-
end
228-
"#{emoji} #{news.title}"
212+
tag_translations[tag_name] || tag_name
229213
end
230214

231-
def news_link_url(news)
232-
# Convert absolute podcast URLs to relative paths for local development
233-
if news.url.match?(%r{^https://coderdojo\.jp/podcasts/\d+$})
234-
news.url.sub('https://coderdojo.jp', '')
235-
else
236-
news.url
237-
end
238-
end
239215
end

app/models/news.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,29 @@ class News < ApplicationRecord
66
uniqueness: true,
77
format: { with: /\Ahttps?:\/\/.*\z/i }
88
validates :published_at, presence: true
9+
10+
def formatted_title
11+
has_custom_emoji = title[0]&.match?(/[\p{Emoji}&&[^0-9#*]]/)
12+
return title if has_custom_emoji
13+
14+
# Add preset Emoji to its prefix if title does not have Emoji.
15+
emoji = case url
16+
when %r{/podcasts/\d+}
17+
'📻'
18+
when %r{prtimes\.jp}
19+
'📢'
20+
else
21+
'📰'
22+
end
23+
"#{emoji} #{title}"
24+
end
25+
26+
def link_url
27+
# Convert absolute podcast URLs to relative paths for local development
28+
if url.match?(%r{^https://coderdojo\.jp/podcasts/\d+$})
29+
url.sub('https://coderdojo.jp', '')
30+
else
31+
url
32+
end
33+
end
934
end

app/views/home/show.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
<ul class="list" style="list-style: none;">
195195
<% @news_items.each do |news| %>
196196
<li>
197-
<%= link_to format_news_title(news), news_link_url(news), target: '_blank' %>
197+
<%= link_to news.formatted_title, news.link_url, target: '_blank' %>
198198
</li>
199199
<% end %>
200200
</ul>

app/views/news/index.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<% @news_items.each do |news| %>
1717
<article class="news-item" style="margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #e0e0e0;">
1818
<h3 style="margin-bottom: 10px;">
19-
<%= link_to format_news_title(news), news.url, target: '_blank', rel: 'noopener' %>
19+
<%= link_to news.formatted_title, news.link_url, target: '_blank', rel: 'noopener' %>
2020
</h3>
2121
<p class="news-meta" style="color: #666; font-size: 14px;">
2222
<i class="fa fa-calendar"></i>
Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,6 @@
11
require 'rails_helper'
22

33
RSpec.describe ApplicationHelper, type: :helper do
4-
describe '#format_news_title' do
5-
it '先頭文字が絵文字ならそのまま返す' do
6-
news = double('news', title: '🔔 新着', url: 'https://news.coderdojo.jp/123')
7-
expect(helper.format_news_title(news)).to eq '🔔 新着'
8-
end
9-
10-
context '先頭文字が絵文字でない場合' do
11-
it 'ポッドキャストのURLには📻を付与する' do
12-
news = double('news', title: 'エピソード33', url: 'https://coderdojo.jp/podcasts/33')
13-
expect(helper.format_news_title(news)).to eq '📻 エピソード33'
14-
end
15-
16-
it 'PR TIMESのURLには📢を付与する' do
17-
news = double('news', title: 'プレスリリース', url: 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html')
18-
expect(helper.format_news_title(news)).to eq '📢 プレスリリース'
19-
end
20-
21-
it 'その他のURLには📰を付与する' do
22-
news = double('news', title: '更新情報', url: 'https://news.coderdojo.jp/2025/12/06/dojoletter')
23-
expect(helper.format_news_title(news)).to eq '📰 更新情報'
24-
end
25-
end
26-
end
27-
28-
describe '#news_link_url' do
29-
it 'ポッドキャストの絶対URLを相対パスに変換する' do
30-
news = double('news', url: 'https://coderdojo.jp/podcasts/33')
31-
expect(helper.news_link_url(news)).to eq '/podcasts/33'
32-
end
33-
34-
it 'その他のURLはそのまま返す' do
35-
news = double('news', url: 'https://news.coderdojo.jp/2025/12/06/dojoletter')
36-
expect(helper.news_link_url(news)).to eq 'https://news.coderdojo.jp/2025/12/06/dojoletter'
37-
38-
news2 = double('news', url: 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html')
39-
expect(helper.news_link_url(news2)).to eq 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html'
40-
end
41-
end
4+
# News関連のメソッドはNewsモデルに移動しました
5+
# spec/models/news_spec.rb を参照
426
end

spec/models/news_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,43 @@
7676
end
7777
end
7878
end
79+
80+
describe '#formatted_title' do
81+
it '先頭文字が絵文字ならそのまま返す' do
82+
news = build(:news, title: '🔔 新着', url: 'https://news.coderdojo.jp/123')
83+
expect(news.formatted_title).to eq '🔔 新着'
84+
end
85+
86+
context '先頭文字が絵文字でない場合' do
87+
it 'ポッドキャストのURLには📻を付与する' do
88+
news = build(:news, title: 'エピソード33', url: 'https://coderdojo.jp/podcasts/33')
89+
expect(news.formatted_title).to eq '📻 エピソード33'
90+
end
91+
92+
it 'PR TIMESのURLには📢を付与する' do
93+
news = build(:news, title: 'プレスリリース', url: 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html')
94+
expect(news.formatted_title).to eq '📢 プレスリリース'
95+
end
96+
97+
it 'その他のURLには📰を付与する' do
98+
news = build(:news, title: '更新情報', url: 'https://news.coderdojo.jp/2025/12/06/dojoletter')
99+
expect(news.formatted_title).to eq '📰 更新情報'
100+
end
101+
end
102+
end
103+
104+
describe '#link_url' do
105+
it 'ポッドキャストの絶対URLを相対パスに変換する' do
106+
news = build(:news, url: 'https://coderdojo.jp/podcasts/33')
107+
expect(news.link_url).to eq '/podcasts/33'
108+
end
109+
110+
it 'その他のURLはそのまま返す' do
111+
news = build(:news, url: 'https://news.coderdojo.jp/2025/12/06/dojoletter')
112+
expect(news.link_url).to eq 'https://news.coderdojo.jp/2025/12/06/dojoletter'
113+
114+
news2 = build(:news, url: 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html')
115+
expect(news2.link_url).to eq 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html'
116+
end
117+
end
79118
end

0 commit comments

Comments
 (0)