2727
2828** 解決策** : スコープの内部実装だけを変更すれば、99%のコードは変更不要!
2929
30- ### 必要な変更は「たった7箇所 」だけ!
30+ ### 必要な変更は「たった8箇所 」だけ!
3131
3232``` ruby
3333# 1. Dojoモデル: スコープ内部実装(2行変更)
3434scope :active , -> { where(inactivated_at: nil ) } # is_active: true → inactivated_at: nil
3535scope :inactive , -> { where.not(inactivated_at: nil ) } # is_active: false → inactivated_at NOT nil
3636
37- # 2. Dojoモデル: active?メソッド(1行変更)
37+ # 2. Dojoモデル: ソート用スコープを追加(新規追加)
38+ scope :order_by_active_status , -> {
39+ # アクティブなDojoを先に、その後に非アクティブなDojoを表示
40+ order(Arel .sql(' CASE WHEN inactivated_at IS NULL THEN 0 ELSE 1 END' ))
41+ }
42+
43+ # 3. Dojoモデル: active?メソッド(1行変更)
3844def active?
3945 inactivated_at.nil? # is_active → inactivated_at.nil?
4046end
4147
42- # 3 . Dojoモデル: sync_active_status削除(削除のみ)
48+ # 4 . Dojoモデル: sync_active_status削除(削除のみ)
4349# before_save :sync_active_status を削除
4450
45- # 4 . Dojoモデル: reactivate!メソッド(1行削除)
51+ # 5 . Dojoモデル: reactivate!メソッド(1行削除)
4652update!(inactivated_at: nil ) # is_active: true を削除
4753
48- # 5. コントローラー: ソート条件(1行変更)
49- .order(Arel .sql(' CASE WHEN inactivated_at IS NULL THEN 0 ELSE 1 END' ), order: :asc )
54+ # 6. コントローラー: ソート条件(読みやすく変更)
55+ @dojos = Dojo .includes(:prefecture )
56+ .order_by_active_status # 新しいスコープを使用
57+ .order(order: :asc )
5058
51- # 6 . Rakeタスク: YAMLからの読み込み(1行削除)
59+ # 7 . Rakeタスク: YAMLからの読み込み(1行削除)
5260# d.is_active = ... この行を削除
5361
54- # 7 . マイグレーション: カラム削除(最後に実行)
62+ # 8 . マイグレーション: カラム削除(最後に実行)
5563remove_column :dojos , :is_active
5664```
5765
@@ -77,28 +85,35 @@ Dojo.where("(is_active = true AND inactivated_at IS NOT NULL) OR (is_active = fa
7785
7886## Step 2: コード変更(10分)
7987
80- 7箇所の変更を実施 :
88+ 8箇所の変更を実施 :
8189
8290``` ruby
8391# 1. app/models/dojo.rb - スコープ(2行)
8492scope :active , -> { where(inactivated_at: nil ) }
8593scope :inactive , -> { where.not(inactivated_at: nil ) }
8694
87- # 2. app/models/dojo.rb - active?メソッド(既に実装済み!そのまま使える)
95+ # 2. app/models/dojo.rb - ソート用スコープを追加
96+ scope :order_by_active_status , -> {
97+ order(Arel .sql(' CASE WHEN inactivated_at IS NULL THEN 0 ELSE 1 END' ))
98+ }
99+
100+ # 3. app/models/dojo.rb - active?メソッド(既に実装済み!そのまま使える)
88101# def active?
89102# inactivated_at.nil? # これは既にPR #1726で実装済み!
90103# end
91104
92- # 3 . app/models/dojo.rb - sync_active_status削除
105+ # 4 . app/models/dojo.rb - sync_active_status削除
93106# before_save :sync_active_status と private メソッドを削除
94107
95- # 4 . app/models/dojo.rb - reactivate!メソッド
108+ # 5 . app/models/dojo.rb - reactivate!メソッド
96109# is_active: true の行を削除
97110
98- # 5. app/controllers/dojos_controller.rb - ソート
99- .order(Arel .sql(' CASE WHEN inactivated_at IS NULL THEN 0 ELSE 1 END' ), order: :asc )
111+ # 6. app/controllers/dojos_controller.rb - ソート(読みやすく!)
112+ @dojos = Dojo .includes(:prefecture )
113+ .order_by_active_status
114+ .order(order: :asc )
100115
101- # 6 . lib/tasks/dojos.rake - is_active設定行を削除
116+ # 7 . lib/tasks/dojos.rake - is_active設定行を削除
102117# d.is_active = ... の行を削除
103118```
104119
@@ -125,9 +140,10 @@ git push && rails db:migrate
125140## 🎯 なぜこのアプローチが優れているか
126141
127142### KISS/YAGNI原則の実践
128- - ** 変更箇所** : わずか7箇所(実質6箇所 、1つは既に実装済み)
143+ - ** 変更箇所** : わずか8箇所(実質7箇所 、1つは既に実装済み)
129144- ** 実装時間** : 30分以内
130145- ** リスク** : 最小限(インターフェースを変えないため)
146+ - ** 可読性** : SQLをスコープに隠蔽して読みやすく
131147- ** ロールバック** : 簡単(スコープ内部を戻すだけ)
132148
133149### Ultrathinking による洞察
@@ -144,11 +160,12 @@ git push && rails db:migrate
144160## 📝 実装チェックリスト
145161
146162- [ ] Step 1: データ整合性確認(Rails console)
147- - [ ] Step 2: 7箇所のコード変更
163+ - [ ] Step 2: 8箇所のコード変更
148164 - [ ] Dojoモデル: スコープ内部実装(2行)
165+ - [ ] Dojoモデル: order_by_active_statusスコープ追加
149166 - [ ] Dojoモデル: sync_active_status削除
150167 - [ ] Dojoモデル: reactivate!メソッド修正
151- - [ ] コントローラー: ソート条件変更
168+ - [ ] コントローラー: ソート条件を読みやすく変更
152169 - [ ] Rakeタスク: is_active行削除
153170- [ ] Step 3: マイグレーション作成と実行
154171- [ ] テスト実行と確認
0 commit comments