LoginSignup
9
9

More than 3 years have passed since last update.

【Ruby on Rails】Fat Controllerの解消〜まずはロジックをモデルへ〜

Posted at

はじめに

今回初投稿となります。
スクールでRuby on Railsを学習し、リファクタリングのカリキュラムもあったのですが、その時点では完成させることに必死で、ロクにリファクタリングもしていなかったので今回ControllerのロジックをModelへ移し、コントローラーをすっきりさせる方法を書いていきます。

そもそもFat Controllerとは?

コントローラー自体の行数が多く、処理の流れを追いにくくなってしまっているControllerの状態を指します(簡単に言えば見通しが悪い)。
スクールでは全く意識せずにControllerに全てのロジックを記述していたが、「実務レベルのコードに近づけたい!」という思いから現在も個人アプリのFat Controllerと闘っています(笑)

切り分ける手順

まずは膨大に膨れ上がったControllerのロジックを全てModelへ移してしまうくらいの気持ちでいきましょう。
Controllerに記述するpublicメソッドはアクションだけで十分です。

そしてロジックを移す先は基本的にModelで問題ないと思います。

例:ユーザーの持つアイテムのみを引っ張ってきたい場合

切り分け前↓

users.controller.rb
def show
  @useritems = Item.includes(:images).where(user_id:(current_user.id)).order(id: "DESC") if user_signed_in?
end

deviseを使用して認証機能を実装しているため、「current_user.id」で現在ログイン中のユーザーのidが取得できます。つまり現在ログイン中のユーザーのマイページ(showアクション)にユーザーのアイテムの情報を引っ張ってきたいわけです。
しかしこのデータの取得、実は「items.controller.rb」のindexアクションでも使用しています。ということでModelにメソッドを定義し、ユーザーのアイテムを取得する記述をまとめたいと思います。

まずはController

users.controller.rb
def show
  @useritems = Item.user_items_get(current_user.id) if user_signed_in?
end

Model側で「current_user」は使用できないので引数で渡します。

続いてModel

Item.rb
def self.user_items_get(user_bigint)
  Item.includes(:images).where(user_id:(user_bigint)).order(id: "DESC")
end

この様にする事でItemControllerのindexアクションでも

items.cotroller.rb
def index
  @useritems = Item.user_items_get(current_user.id).limit(10) if user_signed_in?
end

この様に使用することができます。

Modelにメソッドを書いてControllerで呼び出すとなると、初学者は大層なことに感じてしまいがちですが、Controllerをすっきりさせる上では重要なので是非活用してみて下さい。(しまったこの例行数減ってないや、、、笑)

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9