lonesomewhistle
lonesomewhistle

Reputation: 816

Uninitialized constant in rails 4 w/ grape occuring in deployment only

I'm trying to add a Grape (0.9.0) API to my rails app. It's working perfectly hosted locally on the rails server, but when I try to push to my server using capistrano it fails in the precompile:assets step. here is the stack trace from capistrano:

NameError: uninitialized constant API
/home/deploy/pl2/releases/20141224200546/config/routes.rb:4:in `block in <top (required)>'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/actionpack-4.1.8/lib/action_dispatch/routing/route_set.rb:337:in `instance_exec'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/actionpack-4.1.8/lib/action_dispatch/routing/route_set.rb:337:in `eval_block'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/actionpack-4.1.8/lib/action_dispatch/routing/route_set.rb:315:in `draw'
/home/deploy/pl2/releases/20141224200546/config/routes.rb:1:in `<top (required)>'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:40:in `block in load_paths'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:40:in `each'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:40:in `load_paths'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:16:in `reload!'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:26:in `block in updater'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/activesupport-4.1.8/lib/active_support/file_update_checker.rb:75:in `call'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/activesupport-4.1.8/lib/active_support/file_update_checker.rb:75:in `execute'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:27:in `updater'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/routes_reloader.rb:7:in `execute_if_updated'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application/finisher.rb:71:in `block in <module:Finisher>'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/initializable.rb:30:in `instance_exec'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/initializable.rb:30:in `run'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/initializable.rb:55:in `block in run_initializers'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/initializable.rb:54:in `run_initializers'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application.rb:300:in `initialize!'
/home/deploy/pl2/releases/20141224200546/config/environment.rb:5:in `<top (required)>'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application.rb:276:in `require_environment!'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/railties-4.1.8/lib/rails/application.rb:389:in `block in run_tasks_blocks'
/home/deploy/pl2/shared/bundle/ruby/2.1.0/gems/sprockets-rails-2.0.1/lib/sprockets/rails/task.rb:54:in `block (2 levels) in define'
Tasks: TOP => environment
(See full trace by running task with --trace)
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/command.rb:97:in `exit_status='
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:153:in `block (5 levels) in _execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/channel.rb:551:in `call'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/channel.rb:551:in `do_request'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:561:in `channel_request'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:465:in `dispatch_incoming_packets'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:221:in `preprocess'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:205:in `process'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `block in loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/channel.rb:269:in `wait'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:175:in `block (3 levels) in _execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/channel.rb:514:in `call'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/channel.rb:514:in `do_open_confirmation'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:545:in `channel_open_confirmation'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:465:in `dispatch_incoming_packets'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:221:in `preprocess'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:205:in `process'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `block in loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/net-ssh-2.9.1/lib/net/ssh/connection/session.rb:169:in `loop'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:177:in `block (2 levels) in _execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:191:in `with_ssh'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:136:in `block in _execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:133:in `tap'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:133:in `_execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:66:in `execute'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/capistrano-rails-1.1.2/lib/capistrano/tasks/assets.rake:59:in `block (6 levels) in <top (required)>'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/abstract.rb:85:in `with'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/capistrano-rails-1.1.2/lib/capistrano/tasks/assets.rake:58:in `block (5 levels) in <top (required)>'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/abstract.rb:77:in `within'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/capistrano-rails-1.1.2/lib/capistrano/tasks/assets.rake:57:in `block (4 levels) in <top (required)>'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/backends/netssh.rb:54:in `run'
/Users/briankeane/.rvm/gems/ruby-2.1.2/gems/sshkit-1.6.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
Tasks: TOP => deploy:assets:precompile

in config/application.rb:

module Web
  class Application < Rails::Application
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
    # ... etc
  end
end

in config/routes.rb

Rails.application.routes.draw do
  mount API::Root => "/"   # this is throwing the error (routes.rb:4)
  # ... other routes
end

app/api/API/root.rb:

module API
  class Root < Grape::API
    prefix "api"

    mount API::V1::Root
  end
end

app/api/API/V1/root.rb

module API
  module V1
    class Root < Grape::API
      version "v1"
      format :json
      #error_format :json

      # load the rest of the API
      mount API::V1::Songs
    end
  end
end

and finally, app/api/API/V1/songs.rb

module API
  module V1
    class Songs < Grape::API
      # /api/users
      version "v1"
      format :json

      resource :songs do
        desc "get a song"
        params do
          requires :id, type: Integer, desc: "song_id"
        end
        route_param :id do
          get do
            { title: 'test' }
          end
        end
      end
    end
  end
end

Everything seems to work fine on my local machine, even when I set RAILS_ENV=production. There ia a similar question here, but since it works locally I don't think that's the problem. Thanks!

Upvotes: 0

Views: 729

Answers (2)

FunnyQ
FunnyQ

Reputation: 26

got same issue. I think autoload_paths and paths configurations is the point.

this is files structure:

app
└── api
    └── API
        ├── V1
        │   └── songs.rb
        └── root.rb

so when I changed config/application.rb to:

module Web
  class Application < Rails::Application
    config.paths.add File.join('app', 'api'), glob: File.join('**', '**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '**', '**', '*')]
    # ... etc
  end
end

everything just worked.

Upvotes: 1

lonesomewhistle
lonesomewhistle

Reputation: 816

I'm still looking for a better solution, but here's the hacky thing I did in the meantime to get it up and running just in case someone's experiencing the same issue and needs a quick fix:

At the top of my routes.rb file:

require_relative '../app/api/API/root.rb'

Then in ap/api/API/v1/root.rb:

require_relative 'auth.rb'
require_relative 'songs.rb'
require_relative 'users.rb'

Again -- not thrilled about this solution so any additional help is much appreciated.

Upvotes: 1

Related Questions