LoginSignup
0
3

More than 1 year has passed since last update.

【Rails】コントローラーのリファクタリング

Last updated at Posted at 2021-08-02

はじめに

ポートフォリオで、コントローラーのリファクタリングをやったので、備忘録として記事を書きます。

環境

・Ruby 2.6.3
・Ruby on Rails 5.2.5

リファクタリング1つ目 concemsを使う

共通記述を複数のコントローラーで使う時にやる
app/controllers/concernsにファイルを追加し、必要箇所で読み込ませる

controllers/concerns/search.rb
module Search
  extend ActiveSupport::Concern

  def search
    @keyword = params[:word]
    redirect_to request.referer, notice: "検索文字を入れて下さい" if @keyword.blank?
    searcher = Searcher.new(params[:word].split(/[[:blank:]]+/))

    @users = Kaminari.paginate_array(searcher.users).page(params[:page]).per(12)
    @groups = Kaminari.paginate_array(searcher.groups).page(params[:page]).per(12)
    @posts = Kaminari.paginate_array(searcher.posts).page(params[:page]).per(12)
  end
end

controllers/user/searches_controller.rb
class User::SearchesController < ApplicationController
  include Search
  before_action :search
end
controllers/admin/searches_controller.rb
class Admin::SearchesController < ApplicationController
  include Search
  before_action :search
end

これで同じ記述の箇所はスッキリ〜〜

リファクタリング2つ目 application_controller.rbにかいて継承

複数のコントローラに同じ処理が記述されている場合(継承)に役立つ

controllers/user/●●●●●_controller.rb
class ●●●●●Controller < ApplicationController
  before_action :authorize_owner

  private

  def authorize_owner
    redirect_to root_path unless current_user.owner?
  end
end

authorize_ownerメソッドが定義されていて、このメソッドを複数のコントローラーで使うよ!って時に
application_controller.rbに記載して継承すれば、記述量少なくなります。
※今回はauthorize_ownerメソッド使ってるけど、例として使っているのでどんなメソッドでもいい

controllers/user/application_controller.rb
class ApplicationController < ApplicationController
  private

  def authorize_owner
    redirect_to root_path unless current_user.owner?
  end
end

↓継承したいコントローラーに。

controllers/user/●●●●●_controller.rb
class ●●●●●Controller < ApplicationController
  before_action :authorize_owner
end

リファクタリング3つ目 callbackを利用して共通化

定義したメソッドをbefore_actionなどで共通化させちゃう方法
複数のアクションに同じ処理が記述されている場合に役立つ

controllers/user/●●●●●_controller.rb
class User::PostsController < ApplicationController
  before_action :set_group, only: %i[new index show create update destroy]
  before_action :set_post, only: %i[show update destroy]

  def new
    @post = Post.new
  end

  def index
    @posts = @group.posts.includes(:user).order(updated_at: :desc).page(params[:page]).per(12)
  end

  def show
    @comment = Comment.new

    respond_to do |format|
      format.html do
      end
      format.csv do
        send_data render_to_string, filename: "投稿詳細.csv", type: :csv
      end
    end
  end

 一部アクション割愛 

  private
#ここで記述が重なるコードをメソッド化
  def set_group
    @group = Group.find(params[:group_id])
  end

  def set_post
    @post = Post.find(params[:id])
  end
#ここまで 
#これをbefore_actionで呼び出しちゃえばおk

end


リファクタリング4つ目 王道モデルにメソッド定義

長ったらしいコードをモデルに定義してコントローラーをすっきりしようよ作戦

controllers/user/homes_controller.rb
class User::HomesController < ApplicationController
  def top
    @group_ranks = Group.find(GroupUser.group(:group_id).order("count(group_id) desc").limit(6).pluck(:group_id))  
    @admins = Admin.first(6)
  end
end

#この部分をメソッド化してスッキリさせる#
Group.find(GroupUser.group(:group_id).order("count(group_id) desc").limit(6).pluck(:group_id))  

モデルに定義

models/group.rb
 # ランキング用メソッド
  def self.all_group_ranks
    find(GroupUser.group(:group_id).order("count(group_id) desc").limit(6).pluck(:group_id))
  end

コントローラーに呼び出す

controllers/user/homes_controller.rb
class User::HomesController < ApplicationController
  def top
    @group_ranks = Group.all_group_ranks # Group.rbでメソッド定義
    @admins = Admin.first(6)
  end
end

以上自分が実際にやったリファクタリングでした〜〜

0
3
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
0
3