はじめに
現在、開発中の「小説執筆ツールアプリ」で各ページの共通部品となるサイドバーを設置するに当たって、あまりに非オブジェクト指向な私の書き方を見かねた先輩エンジニアのKさんより、脱ファットコントローラ的な書き方を伝授していただき、それがオブジェクト指向の理解を深める上で非常にヒントとなる内容でしたので、投稿させて頂きます!
サイドバーの中に貼りたいやつ
- ユーザーが執筆登録した小説のタイトル
- その小説の執筆するページへのリンク
これを実現するにはコントローラから、
“現在ログイン中のユーザーの登録した小説のタイトル”と“id”のカラム値
をインスタンス変数で取得する必要がある。
サイドバーを設置するページ
1.執筆一覧ページ
writings_controller.rb
2.タイトル/あらすじページ
novels_controller.rb)
3.プロットページ
plots_controller.rb
4.登場人物ページ
characters_controller.rb)
5.パスワード変更ページ
passwordresets_controller.rb
流れ
①これらのページに対応した各コントローラでidとtitleカラムをインスタンス変数で取得
②コントローラで取得したインスタンス変数を使い、サイドバーのビューに
"ユーザーが執筆登録した小説のタイトル”と"その小説の執筆するページへのリンク”
に描画
③そのビューをパーシャル化して全ページビューに貼ります
良い例・悪い例
今回のアプリのテーブルにはユーザーに該当するauthorsテーブル(current_user)とそのユーザーが登録する小説に該当するnovelsテーブルがあります。
この場合、目的である「ユーザーが登録した小説のタイトル」と「その小説の執筆するページへのリンク」をサイドバーに設置するにはcurrent_user.novelsのnovels(子テーブルの)id、titleカラムが必要になります。
つまり上記5つのコントローラでこのテーブル情報の取得をし、サイドバーのビューにインスタンス変数で渡してあげる必要となりますが、この書き方において、オブジェクト指向に則った良い書き方と悪い書き方を比べてみたいと思います!
悪い例
def index
・
・
@novels_id = current_user.novels.order(created_at: :desc).pluck(:id)
@novels_title = current_user.novels.order(created_at: :desc).pluck(:title)
end
<% @novels_id.zip(@novels_title) do |novels_id, novels_title| %>
<%= link_to "/novels/#{novels_id}/writings/new" do %>
<%= novels_title %>
<% end %>
<% end %>
ユーザーが登録している小説のタイトルとその小説の執筆作成リンク生成のためのidを取得するため明示的に情報取得し、このままビューで扱ういうオブジェクト指向を無視した書き方になります!
この場合、上記5つのコントローラの全アクションで同じ記述が必要になってしまいます>_<
「ログイン中のユーザーが登録した小説」というオブジェクトを扱ったCurrentUsersNovelsコントローラを生成
class CurrentUsersNovelsController < ApplicationController
before_action :set_all_self_novels
def set_all_self_novels
@novels = current_user.novels.order(created_at: :desc)
end
end
この様にbefore_actionでデフォルト取得させてあげれば、このクラスを継承した下位の全クラス
でこのインスタンス変数が使えます!
なので、この記述をして、、
class HogeController < CurrentUsersNovelsController
end
このように該当する5つのコントローラにCurrentUsersNovelsControllerを継承させれば
@novels = current_user.novels.order(created_at: :desc)
がそのコントローラで扱える様になり、下記の様に記述も非常に簡潔にまとまります!
良い例
def index
#その他コード略
end
<% @novels.each do |novel| %>
<%= link_to "/novels/#{novel.id}/writings/new" do %>
<%= novel.title %><br>
<% end %>
<% end %>
</li>
以上です!
かなり初歩的な内容で恐縮ですが、なにか誤りがあればご指摘をいただけるとありがたいです!