【Rails5】数時間溶かしたエラーの原因はRoutingにあった

長時間悩んだ末にエラーが解決できると, なんとも言えない達成感があります. それと同時に,「俺の時間があああ」とも思いますが...

今回時間を奪ったものは正確に言うと, エラーではなくテストです. 何度やってもテストが通りませんでした.

しかしエラーも引き起こし得るミスですから気をつけたいところですね. ただしRESTfulにRoutingを組んでおけば起ることのない事態ですから, もっとRESTを意識しておけばよかったのかもしれません.

間違ったコード

テストが通らなかった状態では, 以下のような記述をしていました.

# routes.rb
get :account_activation, to: 'account_activations#activate'
# account_activations_controller.rb
def activate
  # params[:id] を使う処理
end

なにがまずいのか

上のRoutingではnamed pathの挙動が以下のようになります.

irb(main)> app.account_activation('IdForActivation')
=> "/account_activation.IdForActivation"

本当はaccount_activation/IdForActivationというパスになって欲しいのに, そうはなっていないんですね.

正しいコード

:idを使うことをRailsに教えてやればOKです.

# routes.rb
get 'account_activation/:id', to: 'account_activations#activate', as: :account_activation

asオプションは, named pathを設定するためのものです. これがないとnamed pathが使えませんでした.

補足とまとめ

はじめにも述べたように, resourcesresourceメソッドを用いてRESTfulにRoutingを組んでいれば起こらないミスでした. もしRESTfulにするならば,

resources :account_activations, only: [:edit]

のように書けばよかったですね. もちろんこの場合はアクション名もactivateからeditに変わりますが.

今回得た学びは, 便利メソッドがやってくれていることを理解しよう ということですね.

resourcesというメソッドは7つものRoutingを一気に設定してくれます. しかしカスタマイズされたRoutingを設定したい場合は, resourcesの仕事を肩代わりしなくてはなりません. そのためにはその仕事内容を理解する必要があるということでした.