【问题标题】:NoMethodError: undefined method `[]' for nil:NilClass for assets:precompile on herokuNoMethodError:nil 的未定义方法“[]”:资产的 NilClass:heroku 上的预编译
【发布时间】:2015-04-19 06:44:21
【问题描述】:

一个使用 devise 和 omniauth 的应用在 localhost 上运行良好,但是当我在 heroku 上部署它时,我得到一个错误:

-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       NoMethodError: undefined method `[]' for nil:NilClass
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/config/initializers/omniauth.rb:6:in `block in <top (required)>'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/omniauth-1.2.2/lib/omniauth/builder.rb:6:in `initialize'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:43:in `new'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:43:in `build'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:118:in `block in build'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:118:in `each'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:118:in `inject'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/stack.rb:118:in `build'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/engine.rb:498:in `app'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/application/finisher.rb:36:in `block in <module:Finisher>'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/initializable.rb:30:in `instance_exec'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/initializable.rb:30:in `run'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/initializable.rb:55:in `block in run_initializers'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/initializable.rb:54:in `run_initializers'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:300:in `initialize!'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/config/environment.rb:5:in `<top (required)>'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `block in require'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:276:in `require_environment!'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:379:in `block in run_tasks_blocks'
       /tmp/build_e711adadeab2d8cb9d37632e4c0ba08b/vendor/bundle/ruby/2.1.0/gems/sprockets-rails-2.2.2/lib/sprockets/rails/task.rb:64:in `block (2 levels) in define'
       Tasks: TOP => environment
       (See full trace by running task with --trace)
 !
 !     Precompiling assets failed.
 !

 !     Push rejected, failed to compile Ruby app

To git@heroku.com:my-app.git
 ! [remote rejected] master -> master (pre-receive hook declined)

这是 Gemfile 和omniauth 文件:

#Gemfile:
#....
gem 'google-api-client'
gem 'omniauth'
gem 'omniauth-google-oauth2'
gem 'devise'
#.....


#config/initializers/omniauth.rb

# probably this isn't necessary
if Rails.env.production?
  OmniAuth.config.full_host = 'https://my-app.herokuapp.com'
end

# but it is necessary
Rails.application.config.middleware.use OmniAuth::Builder do
  provider(:google_oauth2, $ga_client['client_id'], $ga_client['client_secret'], 
    { scope: 'userinfo.profile, userinfo.email, analytics', access_type: 'offline', prompt: 'consent' }
  )
end

【问题讨论】:

  • 第 6 行是“结束”,是您部署的omniauth 文件吗?
  • @RichardAE,它指向provider(:google_oauth2, .....线。

标签: ruby-on-rails ruby ruby-on-rails-4 heroku devise


【解决方案1】:

我遇到了同样的问题。这个问题的原因是Rails使用了一个名为sqlite3的数据库系统,Heroku没有使用这个数据库。要解决此问题,请进入您的 Gemfile 并向下滚动,直到您看到类似这样的内容

group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 2.0'
end

注意:如果您使用低于 Rails 4.0.0 的任何版本,您将不会拥有该组,只需创建它即可。

现在在 Gemfile 顶部的某处,将有一行显示

gem 'sqlite3'

将此行移到 Development, Test Group 这现在只会在开发中运行。您现在可以尝试通过编写再次创建您的 Heroku 应用程序

$ heroku create

那么您可能需要迁移您的数据库。通过运行来做到这一点

$ rake db:migrate

现在推送到 Heroku

$ heroku push

应该可以!

希望我能帮上忙;)

【讨论】:

  • 这与error和stacktrace无关
【解决方案2】:

在您的代码中,$ga_client 为零。您没有在文件中的任何地方定义这样的数组,如果在其他地方定义,则在执行此初始化程序时不会加载它。

按照文档中的建议,尝试使用环境变量设置 client_id 和 client_secret。

provider :google_auth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET']

【讨论】:

  • $ga_clientinitializers/ga.rb 中定义。在执行omniauth.rb的时候还没有执行吗?
  • 堆栈跟踪说它为零。在其他文件中定义它不会使其在此处可用
  • 它是一个全局变量,应该是可见的。
  • 我认为你误解了 $ 变量。在 ruby​​ 中,这些不是全局变量。检查此以了解 $ 在 ruby​​ 中的某些用途:jimneath.org/2010/01/04/…
  • 你是说Variables starting with $ are global, 是假的吗?
【解决方案3】:

全局变量未初始化:

# but it is necessary

Rails.application.config.middleware.use OmniAuth::Builder do
  provider(:google_oauth2, $ga_client['client_id'], $ga_client['client_secret'], 
    { scope: 'userinfo.profile, userinfo.email, analytics', access_type: 'offline', prompt: 'consent' }
  )
end

# ops $ga_client is nil

当我将上面的代码替换为:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"]
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多