Railsアプリで初めて自作ヘルパーを使ってリファクタリングした話

#はじめに
今までRuby on Railsでアプリケーションを作成していて
ふと気になったことがありました。

コントローラー作成時に毎回ついてくるコイツ
〇〇_helper.rb
このファイル何に使うんだろ...。
ヘルパーって書いてあるからヘルパーメソッドに関係しているのかな...??

この時、私は
"わざわざ同時に作成される物だからきっと便利なファイルに違いない"
と、興味の向くままにQiitaで解説記事などを調べてみました。

#結論
自作のヘルパーメソッドを記述するファイルのようです。
（自作ヘルパー == カスタムヘルパー と言うらしい）
ヘルパーメソッドは今日の今日までGemに用意されているモノしか使用したことがなかったので
これは便利そうだ、と直感で思いました。

#さっそく使ってみた
他の方のQiita記事を参考にさせていただき
今回は個人開発したアプリのコードリファクタリングに使用してみました。
コントローラー内のリファクタリング内容を本記事の内容にします。

###環境
Rails 5.2.3
Ruby 2.5.1

###使い方


まずはリファクタリングをするコントローラーを見ていきましょう。

```ruby:users_controller.rb
class UsersController < ApplicationController

~省略~

  private
  def set_user
    @user = User.find(params[:id])
  end

  def check_user
    redirect_to new_user_registration_path, alert: 'ログインまたは新規登録をお願いします' unless current_user.id == @user.id
  end
end
```

~~check_userというメソッド内のunless以下がイケてないので~~
ヘルパーメソッドを作成してリファクタリングします。

（2020年9月13日 追記）
下記の記事にてif!よりもunlessの方が読み手に負荷がかかりにくいという解説がされているのですが、私の配慮が足りなかったために雑なリファクタリングを実施しています。
あくまでリファクタリングをする際は
①記述量を減らす。
②読みやすいコードに整える。
の観点で実施する事をオススメします。

▼参考記事▼
[[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか](https://qiita.com/jnchito/items/dedb3b889ab226933ccf)
<br><br>

```ruby:helpers/users_helper.rb
module UsersHelper

  def current_user?(user)
    current_user.id == user.id
  end

end
```
current_user?というヘルパーメソッドを作成しました。
このメソッド名および内容はけっこう定番のようです。
<br>
helpersというディレクトリ直下に
application_helper.rbというファイルもありますが
これは複数のコントローラーやビューに適用させるヘルパーメソッドを管理するファイルのようです。
※今回は未使用
<br>
さっそく作成したヘルパーメソッドをコントローラー内に適用させましょう。

```ruby:users_controller.rb
class UsersController < ApplicationController
  include UsersHelper

~省略~

  private
  def set_user
    @user = User.find(params[:id])
  end

  def check_user
    redirect_to new_user_registration_path, alert: 'ログインまたは新規登録をお願いします' if !current_user?(@user)
  end
end
```

###説明
コントローラー内でhelperファイルの自作ヘルパーを使う際は
2行目のようにincludeで読み込み必要があるそうです。
※筆者はコントローラー名とヘルパーファイル名が対応してるから勝手にやってくれるんやろうな
 と、Rails特有の処理が入ると勝手に思い込んでいましたが記述が必要なようです。
<br>
リファクタリング内容ですが
set_userで定義された@userを引数に渡して
先ほど作成したcurrent_user?メソッドを使用しました。

また、unlessという記述もif !~という記述に変更しました。
これで少しはコードがスッキリしました。
<br>
<br>
同じような内容でposts_controllerもリファクタリングします。

```ruby:posts_controller.rb
class PostsController < ApplicationController
  

  def edit
    redirect_to new_user_registration_path, alert: 'ログインをお願いします' unless current_user.id == @a_post.user_id
  end

  def destroy
    redirect_to new_user_registration_path, alert: 'ログインをお願いします' unless current_user.id == @a_post.user_id
    if @a_post.destroy
      redirect_to root_path, notice: '投稿を削除しました'
    else
      render :show, notice: '投稿が削除できませんでした'
    end
  end


  private

  def set_post
    @a_post = Post.find(params[:id])
  end
end

```

こちらもunless以下の記述を修正していきます。

まずはヘルパーメソッドを作成。

```ruby:helpers/posts_helper.rb
module PostsHelper

  def current_user_post?(a_post)
    current_user.id == a_post.user_id
  end

end

```

これをコントローラーに適用していきます。

```ruby:posts_controller.rb
class PostsController < ApplicationController
  include PostsHelper

  def edit
    redirect_to new_user_registration_path, alert: 'ログインをお願いします' if !current_user_post?(@a_post)
  end

  def destroy
    redirect_to new_user_registration_path, alert: 'ログインをお願いします' if !current_user_post?(@a_post)
    if @a_post.destroy
      redirect_to root_path, notice: '投稿を削除しました'
    else
      render :show, notice: '投稿が削除できませんでした'
    end
  end

  private

  def set_post
    @a_post = Post.find(params[:id])
  end
end

```

こちらもヘルパーを読み込んでリファクタリングしたら完了です。

#最後に
今回はコントローラーに絞って記事を書きましたが自作ヘルパーはもちろんビューにも使用できます。
また、ビューに使用する場合はコントローラーと違って、読み込みの記述が必要ないみたいですね。
私もこのあとビューファイルのコードをリファクタリングしようと思います。

どこか不備がありましたらコメントにてご指摘いただけると幸いです。

#参考記事
- [Rails5.0でのヘルパー読み込みと優先順位](https://qiita.com/rjge/items/562545fd5d2a9e7aa35e)
- [Railsヘルパーメソッドのまとめ（よく使うもの）](https://qiita.com/Yukaaaah/items/19e524fd0c0e4a3451f1)