LoginSignup
10
9

More than 5 years have passed since last update.

GrapeでActiveAdminを使おうとして泥沼にハマった話

Posted at

背景

grapeactiveadminを使って、APIの管理画面を作りたかった。
両者とも基本に忠実に、ちょっと手を加えた程度の作り込みだったのがずっと以下のエラーが出てしまった。

load_missing_constant': Unable to autoload constant Base,
expected /vagrant/app/apis/api/base.rb to define it (LoadError)

問題

Grapeの記事は色々まとめられていて、
下記のリンクを見れば分かる通り多くの人がAPI::Baseという形でnamespaceを確保し、
base.rbapplication.rbのような扱いで利用している。

自分も同じようにAPI::Baseでmountして、
base.rbapplication.rbとしてモリモリ作り込んでいた。

apis
└── api
    ├── base.rb
    └── v2
        ├── base.rb
        ├── books.rb
        └── users.rb

ある程度作った時に、ActiveAdminを入れてみるとエラーが起きた。

load_missing_constant': Unable to autoload constant Base,
expected /vagrant/app/apis/api/base.rb to define it (LoadError)

その時の設定はこんな感じ

routes.rb
Rails.application.routes.draw do
  devise_for :admin_users, ActiveAdmin::Devise.config
  ActiveAdmin.routes(self)

  mount API::Base => '/'
end
config/application.rb
module AppName
  class Application < Rails::Application
    config.paths.add File.join('app', 'apis'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'apis', '*')]
    config.middleware.use(Rack::Config) do |env|
      env['api.tilt.root'] = Rails.root.join 'app', 'views', 'apis'
    end
  end
end
apis/api/base.rb

module API
  class Base < Grape::API

    mount V2::Base
  end
end

エラーメッセージでは/vagrant/app/apis/api/base.rbでBaseを定義してよ!と言われているのだが、ちゃんとしている。
どちらももう一方を読み込まなければ動くので、何かの噛み合わせが悪いようだ。

原因

/home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:495:in `load_missing_constant': Unable to autoload constant Base, expected /vagrant/app/apis/api/base.rb to define it (LoadError)
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:184:in `const_missing'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:526:in `load_missing_constant'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:184:in `const_missing'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/inflector/methods.rb:263:in `const_get'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/inflector/methods.rb:263:in `block in constantize'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/inflector/methods.rb:259:in `each'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/inflector/methods.rb:259:in `inject'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/inflector/methods.rb:259:in `constantize'
    from /home/vagrant/.gem/ruby/2.2.2/gems/activesupport-4.2.1/lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
    from /home/vagrant/.gem/ruby/2.2.2/gems/inherited_resources-1.6.0/lib/inherited_resources/class_methods.rb:317:in `initialize_resources_class_accessors!'
    from /home/vagrant/.gem/ruby/2.2.2/gems/inherited_resources-1.6.0/lib/inherited_resources/class_methods.rb:394:in `inherited'
    from /home/vagrant/.gem/ruby/2.2.2/bundler/gems/active_admin-28e8a8f36640/lib/active_admin/base_controller/authorization.rb:2:in `<module:ActiveAdmin>'
    from /home/vagrant/.gem/ruby/2.2.2/bundler/gems/active_admin-28e8a8f36640/lib/active_admin/base_controller/authorization.rb:1:in `<top (required)>'

エラーlogを見てみるとactiveadminのauthorize.rbがエラーを出していた。
が、どうやらactiveadminがGrapeのBaseを読みに行ってエラーを吐いているらしい。

解決

以下のようにbaseというクラス名を変更した。

```sh
apis
└── api
    ├── api_base.rb
    └── v2
        ├── v2_base.rb
        ├── books.rb
        └── users.rb
routes.rb
Rails.application.routes.draw do
  devise_for :admin_users, ActiveAdmin::Devise.config
  ActiveAdmin.routes(self)

  mount API::ApiBase => '/'
end
api_base.rb
module API
  class ApiBase < Grape::API

    mount V2::V2Base
  end
end

根本的な解決にはなっていないかもしれないけど、とりあえずこれで動いたので一安心。
皆さんもハマらないように気をつけて下さい。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9