この記事はRuby, Railsを学習中の者が課題に取り組んでいる時に遭遇した問題について取り上げたものです。解決方法が正しくない、内容が間違っている場合はご指摘頂けると幸甚です。
今回は機能の実装が終わってrubocopにコードの確認をしてもらった際に遭遇した違反(offense)内容に対する対策を備忘録も兼ねて記事にしたいと思います。
※rubocopの設定は使用している企業や環境によって異なります。
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
のアクション内容は以下の通りです。
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なども変更しています。
これでこの違反内容は解決できました。
続いても同じ違反内容の対応です。
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
(ローカル変数)に代入してその値を返すというものです。
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ボタンを押せば全て変更してくれます。
ただ、この作業を進めながらふと疑問が湧いてきました。
全てのアクション名を
create
, destroy
, edit
, index
, new
, show
, update
の中から選定するなんてできるのか?と。
今回のcurrent_cart
からupdate
への変更も若干こじ付けのような変更で初見の人がこのコードを見たらupdate
というアクション名から機能を想像することができるのだろうか?と。
勿論コードの内容を見れば機能の中身を理解することはできるけど、名前と機能の間に関連性が見出せないです。
そんな感じで悩んでいた所、rubocopから違反指摘されたアクション以外に指定の名前を使用していないアクションが複数存在しました。
それはprivateメソッドです。
どうやらpublicメソッドにはアクション名の違反はあるものの、privateメソッドには名前の指定は無いようでした。
幸い私が違反していたアクションはprivateに切り替えても問題ありませんでしたので、アクション名を変更することなく違反内容をクリアすることができました。
60 files inspected, no offenses detected