RubocopにUse only specific action names (create, destroy, edit, index, new, show, update).と指摘された場合

この記事はRuby, Railsを学習中の者が課題に取り組んでいる時に遭遇した問題について取り上げたものです。解決方法が正しくない、内容が間違っている場合はご指摘頂けると幸甚です。

今回は機能の実装が終わってrubocopにコードの確認をしてもらった際に遭遇した違反(offense)内容に対する対策を備忘録も兼ねて記事にしたいと思います。
※rubocopの設定は使用している企業や環境によって異なります。

```ruby:
app/controllers/carts_controller.rb:6:7: C: Hc/RailsSpecificActionName: 
Use only specific action names (create, destroy, edit, index, new, show, update).
  def add_merchandise
      ^^^^^^^^^^^^^^^
```
内容としては具体的なアクション名については下記の7通りの名前だけを使うようにとの指示。
`create`, `destroy`, `edit`, `index`, `new`, `show`, `update`

そして、`add_merchandise`のアクション内容は以下の通りです。
```ruby:carts_controller.rb - add_merchandise
  def add_merchandise
    @merchandise = Merchandise.find_by(id: params[:format])

    check_quantity

    return if params[:quantity].to_i <= 0 || params[:quantity].blank?

    if @cart_item.save
      flash[:notice] = '商品が追加されました。'
      redirect_to merchandises_path and return
    else
      @merchandises_limit = Merchandise.with_attached_image.order(id: 'DESC').limit(4)
      redirect_to merchandise_path, alert: '商品の追加に失敗しました。' and return
    end
  end

private

  def check_quantity
    if params[:quantity].to_i <= 0 || params[:quantity].blank?
      @merchandises_limit = Merchandise.with_attached_image.order(id: 'DESC').limit(4)
      flash[:alert] = '数量は1以上の整数を入力して下さい。'
      redirect_to merchandise_path(@merchandise) and return
    elsif @cart_item.nil?
      @cart_item = current_cart.cart_items.build(merchandise_id: @merchandise.id)
      @cart_item.quantity += params[:quantity].to_i
    elsif @cart_item.merchandise_id == @merchandise.id
      @cart_item.quantity += params[:quantity].to_i
    end
  end
```
内容としてはECサイトでカート内に商品を追加する機能です。
アクション名を7つから選ぶということなので、カート内のデータを作るという意味合いで`create`に変更しました。
※アクション名が変わるので、routes, viewなども変更しています。
これでこの違反内容は解決できました。


続いても同じ違反内容の対応です。
```ruby
app/controllers/application_controller.rb:8:7: C: Hc/RailsSpecificActionName: 
Use only specific action names (create, destroy, edit, index, new, show, update).
  def current_cart
      ^^^^^^^^^^^^
```
`current_cart`アクションはセッション情報から`cart_id`項目のデータを取得する、若しくはセッション情報が無ければ、モデルから新しくインスタンスを作成してそこから`cart_id`を取得して`current_car`(ローカル変数)に代入してその値を返すというものです。
```ruby:application_controller.rb - curren_cart
  def current_cart
    # cart_idをsessionに持つカードがあれば代入、無ければ新しく作って代入
    current_cart = Cart.find_by(id: session[:cart_id]) || Cart.create
    # cart_idが入ったsessionがあればそのまま使う。無ければcurrent_cartのidを代入
    session[:cart_id] ||= current_cart.id
    # カート情報を返す
    current_cart
  end
```
カート情報を新しく作成したり、取得したりすることで最新の情報にするという意味合いで`update`に変更してみることにしました。
このアクションは特にviewやpathなどに影響を与えないので、各controller内の名称だけ変更する必要がありました。
変更する際はVisual Studio CodeのReplace All機能が役立ちました。
左端の虫眼鏡マークで`current_cart`を検索して、該当箇所を全て洗い出し、検索欄の下に置き換え後の文字列を入力してReplace Allボタンを押せば全て変更してくれます。
![current_cart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508918/63906785-0342-f21e-978a-5e7c6d36dc40.png)

ただ、この作業を進めながらふと疑問が湧いてきました。
全てのアクション名を
`create`, `destroy`, `edit`, `index`, `new`, `show`, `update`
の中から選定するなんてできるのか？と。

今回の`current_cart`から`update`への変更も若干こじ付けのような変更で初見の人がこのコードを見たら`update`というアクション名から機能を想像することができるのだろうか？と。
勿論コードの内容を見れば機能の中身を理解することはできるけど、名前と機能の間に関連性が見出せないです。
そんな感じで悩んでいた所、rubocopから違反指摘されたアクション以外に指定の名前を使用していないアクションが複数存在しました。
それはprivateメソッドです。
どうやらpublicメソッドにはアクション名の違反はあるものの、privateメソッドには名前の指定は無いようでした。
幸い私が違反していたアクションはprivateに切り替えても問題ありませんでしたので、アクション名を変更することなく違反内容をクリアすることができました。
```ruby
60 files inspected, no offenses detected
```