Skip to content

Commit 22b4622

Browse files
committed
✨ News モデルに to_type メソッドとURL定数を追加
News モデルをリファクタリング: - to_type メソッドを追加(ニュースの種類を日本語で返す) - ポッドキャスト、プレスリリース、お知らせ、ニュース - URL パターンを定数として定義 - URL_ROOT: CoderDojo.jp のルートドメイン(正規表現) - ROOT_DOMAIN: ドメイン文字列(文字列置換用) - URL_PODCAST, URL_PRTIMES, URL_NEWS: 各サービスのパターン - formatted_title と link_url メソッドで定数を使用 - セキュリティ改善: ^を\Aに変更(Ruby正規表現のベストプラクティス) ニュース一覧ページに種類を表示: - 日付の横にニュースの種類を表示するように改善 テストカバレッジ: - to_type メソッドの完全なテストカバレッジを追加 - 全211テストが成功
1 parent caa50f0 commit 22b4622

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

app/models/news.rb

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
class News < ApplicationRecord
2+
# URL patterns
3+
URL_ROOT = %r{\Ahttps://coderdojo\.jp}.freeze
4+
URL_PODCAST = %r{coderdojo\.jp/podcasts/\d+}.freeze
5+
URL_PRTIMES = %r{prtimes\.jp}.freeze
6+
URL_NEWS = %r{news\.coderdojo\.jp}.freeze
7+
ROOT_DOMAIN = 'https://coderdojo.jp'.freeze
8+
29
scope :recent, -> { order(published_at: :desc) }
310

411
validates :title, presence: true
@@ -12,9 +19,9 @@ def formatted_title
1219
return title if has_custom_emoji
1320

1421
# Add preset Emoji to its prefix if title does not have Emoji.
15-
emoji = if url.match?(%r{/podcasts/\d+})
22+
emoji = if url.match?(URL_PODCAST)
1623
'📻'
17-
elsif url.match?(%r{prtimes\.jp})
24+
elsif url.match?(URL_PRTIMES)
1825
'📢'
1926
elsif title.include?('寄贈')
2027
'🎁'
@@ -26,15 +33,26 @@ def formatted_title
2633

2734
def link_url
2835
# Convert absolute podcast URLs to relative paths for local development
29-
if url.match?(%r{^https://coderdojo\.jp/podcasts/\d+$})
30-
url.sub('https://coderdojo.jp', '')
36+
if url.match?(URL_PODCAST) && url.match?(URL_ROOT)
37+
url.sub(ROOT_DOMAIN, '')
3138
else
3239
url
3340
end
3441
end
3542

3643
def internal_link?
3744
# Check if the link is internal (coderdojo.jp domain)
38-
url.match?(%r{^https://coderdojo\.jp}) || url.start_with?('/')
45+
url.match?(URL_ROOT) || url.start_with?('/')
46+
end
47+
48+
def to_type
49+
# Return the type of news based on URL domain
50+
case url
51+
when URL_PODCAST; 'ポッドキャスト'
52+
when URL_PRTIMES; 'プレスリリース'
53+
when URL_NEWS; 'お知らせ'
54+
else
55+
'ニュース'
56+
end
3957
end
4058
end

app/views/news/index.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<p class="news-meta" style="color: #666; font-size: 14px;">
4141
<!--<i class="fa fa-calendar"></i>-->
4242
<%= l(news.published_at.to_date, format: :long) if news.published_at %>
43+
&ndash; <%= news.to_type %>
4344
</p>
4445
</article>
4546
<% end %>

spec/models/news_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,26 @@
156156
end
157157
end
158158
end
159+
160+
describe '#to_type' do
161+
it 'coderdojo.jp/podcasts のURLは「ポッドキャスト」を返す' do
162+
news = build(:news, url: 'https://coderdojo.jp/podcasts/33')
163+
expect(news.to_type).to eq 'ポッドキャスト'
164+
end
165+
166+
it 'prtimes.jp のURLは「プレスリリース」を返す' do
167+
news = build(:news, url: 'https://prtimes.jp/main/html/rd/p/000000001.000038935.html')
168+
expect(news.to_type).to eq 'プレスリリース'
169+
end
170+
171+
it 'news.coderdojo.jp のURLは「お知らせ」を返す' do
172+
news = build(:news, url: 'https://news.coderdojo.jp/2025/12/06/dojoletter')
173+
expect(news.to_type).to eq 'お知らせ'
174+
end
175+
176+
it 'その他のURLは「ニュース」を返す' do
177+
news = build(:news, url: 'https://example.com/article')
178+
expect(news.to_type).to eq 'ニュース'
179+
end
180+
end
159181
end

0 commit comments

Comments
 (0)