問題
Rails 5.2.0.beta2
で開発中、何故か画像がリンク切れする。
コードはドキュメント通り書いている。画像も指定の場所に上がっている。
app/views/accounts/show.html.slim
= image_tag url_for(@account.avatar)
原因
route.rb
でのエラー処理の記述が問題だった。
route.rb
の一番最後に、以下のように記述して、エラーページを表示していた。
config/route.rb
Rails.application.routes.draw do
...
get "*path", controller: 'application', action: 'error404', via: :all
end
ところが、ActiveStrageは画像のリンクを、以下のように見ているらしい。
rails/activestorage/config/routes.rb
Rails.application.routes.draw do
get "/rails/active_storage/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob, internal: true
...
end
project/config/route.rb
がrails/activestorage/config/routes.rb
よりも先に呼ばれるので、画像を呼ぶ前に、エラーページの方を呼んでしまう。
解決方法
エラーハンドリングに関する別の問題(上記のrouteでの記述では、RoutingErrorをキャッチできない)の記事を参考にした。
それと同じ方法でエラー処理するようにしたら解決した。
以下のファイルを作成して、route.rb
の記述を削除。サーバを再起動する。
config/initilizers/exceptions_app.rb
Rails.application.configure do
config.exceptions_app = ErrorsController.action(:show)
end
app/controllers/error_controller.rb
class ErrorsController < ApplicationController
skip_after_action :verify_authorized
layout 'application'
rescue_from StandardError, with: :error500
rescue_from ActionController::RoutingError, with: :error404
rescue_from ActiveRecord::RecordNotFound, with: :error404
def error404(exception = nil)
logger.info "Rendering 404 with exception: #{exception.message}" if exception
render template: 'errors/error404', status: 404
end
def error500(exception = nil)
logger.info "Rendering 500 with exception: #{exception.message}" if exception
render template: 'errors/error500', status: 500
end
def show
raise
end
end
詳細は以下の参考のリンクから。
参考
- Railsの ActionController::RoutingError は ApplicationController での rescue_from で捕まえられない:
https://qiita.com/gaaamii/items/183a9a3091a1751d833a - Railsアプリの例外ハンドリングとエラーページの表示についてまとめてみた:
https://qiita.com/upinetree/items/273ae574f1c021d24c37#exceptions_app%E3%81%AB%E3%82%88%E3%82%8B%E4%BE%8B%E5%A4%96%E6%8D%95%E6%8D%89