4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Organization

Rails6でknockを導入してload関連のエラーが発生したときの対処法

Ruby on Rails 6.0.0 で作成したアプリケーションに、JWTトークンの発行・認証を行う目的で knock をインストールしようとしたところ、loadに関するエラーが発生したので対処法をまとめます。

発生したエラー

現象1

rails generate knock:install を実行するとwarningとerrorが出力される。
config/initializers/knock.rb の生成自体はできている。

$ rails generate knock:install                                                                                                                                                               
Running via Spring preloader in process 14337
[WARNING] Could not load generator "generators/knock/install_generator". Error: expected file /home/user/.rbenv/versions

現象2

ApplicationController にて Knock::Authenticable をincludeさせると、railsが起動できない。

$ rails c                                                                                                                                                                                     
/home/user/Documents/develop/knock_test/app/controllers/application_controller.rb:2:in `<class:ApplicationController>': uninitialized constant Knock::Authenticable (NameError)

原因

Rails6でのautoloadがzeitwerkモードに変更となったことで、autoloadの挙動がRails5以前と変わったことに起因しています。

Rails 6 zeitwerk autoload problem with gem

対処法

対処法1. 明示的にrequireする[推奨]

上記issueにある通り、明示的にソースをrequireすることでエラーを回避できます。

config/initializers/eager_load_knock.rb
require 'knock/version'
require 'knock/authenticable'

対処法2. autoloadをclassicモードに戻す[非推奨]

Rails5以前と同じ方法でautoloadさせることでもエラーを回避できます。
基本的には新しいバージョンに追従すべきなので非推奨ですが、他のgemで同様のエラーが発生する場合などはこちらの方が手っ取り早いかもしれません。

config/application.rb
require_relative 'boot'

require "rails"
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "rails/test_unit/railtie"

Bundler.require(*Rails.groups)

module KnockTest
  class Application < Rails::Application
    config.load_defaults 6.0
    config.api_only = true
    config.autoloader = :classic # ★追記
  end
end

まとめ

こちらの issueで何かしら修正が入ることに期待しつつ、まずは上記のような対策でエラーを回避するしかなさそうです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
4
Help us understand the problem. What are the problem?