deviseで認証処理を実装時、confirmableのデフォルトだと、認証メールクリック時にActionController::UnknownFormat
エラーが出た。
confirmations/show
のviewが無い。
認証成功時にログイン画面に飛ばしつつ、認証失敗時にconfirmations/show
をエラー画面として表示する。
versionは以下。
ruby: 2.6.5
rails: 6.0.1
devise: 4.7.1
confirmations_controllerのshowメソッドをoverride
controllers/users/confirmations_controller.rb
class Users::ConfirmationsController < Devise::ConfirmationsController
...
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.find_by_confirmation_token(params[:confirmation_token])
if resource.nil? || resource.confirmed?
# トークンが不正な場合、アカウント登録(パスワード登録)が済んでいる場合
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
render :show
elsif resource.is_confirmation_period_expired?
# アカウント登録メールの期限が切れた場合
resource.errors.add(:email, :confirmation_period_expired,
period: Devise::TimeInflector.time_ago_in_words(resource_class.confirm_within.ago))
render :show
else
# activate
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
redirect_to new_user_session_path, notice: 'メールアドレスを確認しました。'
end
end
...
end
メソッド追加
models/users.rb
def is_confirmation_period_expired?
# メールアドレス確認メール有効期限チェック(期限はconfig/initializers/devise.rbのconfirm_withinで設定)
self.confirmation_period_expired?
end
controllers/show のviewを作成
views/users/confirmations/show.html.erb
<h2>エラー画面</h2>
<% if resource.errors.any? %>
<article class="message is-danger">
<div class="message-header">
<p><%= pluralize(resource.errors.count, "error") %> prohibited this service from being saved:</p>
<button class="delete" aria-label="delete"></button>
</div>
<div class="message-body">
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
</article>
<% end %>
routesも忘れずに
config/routes.rb
...
devise_for :users,
controllers: {
...
confirmations: 'users/confirmations',
...
},
...
devise_scope :user do
put 'confirmation', to: 'users/confirmations#show', as: :back_confirmation
...