Rails 图片上传的 CarrierWave 报错

aini · 2018年09月21日 · 最后由 ken 回复于 2018年09月22日 · 1295 次阅读

问题详情

上传图片配置在本地是正常的,push 到 heroku 之后就报错了,报错信息如下:

remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...

在 stackoverflow 的解决方式如下:
config/application.rb

config.assets.initialize_on_precompile = false

修改之后再次 push 报错依然,运行如下命令查看一下 heroku 的日志

heroku logs --tail

看到如下报错信息:

2018-09-21T03:02:11.684933+00:00 app[web.1]: [4] ! Unable to load application: NameError: uninitialized constant CarrierWave::Storage::Fog
2018-09-21T03:02:11.685158+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.4.0/bin/puma)
2018-09-21T03:02:11.685334+00:00 app[web.1]: NameError: uninitialized constant CarrierWave::Storage::Fog

stackoverflow 上的解决方式试过一遍了还是报这个错误
[ https://stackoverflow.com/questions/29915571/nameerror-uninitialized-constant-carrierwavestoragefog-in-heroku-logs ]
[ https://stackoverflow.com/questions/35174399/nameerror-uninitialized-constant-carrierwavestoragefog ]
[ https://github.com/carrierwaveuploader/carrierwave/issues/2023 ]

如下是我的相关文件
config/initializers/carrier_wave.rb

if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
    config.fog_directory = ENV['S3_BUCKET']
  end
end

app/uploaders/picture_uploader.rb

class PictureUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process resize_to_limit:[400, 400]

  if Rails.env.production?
    storage :fog
  elsif Rails.env.development?
    storage :file
  end 

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

补充

在 push 前我还执行了 如下命令:

$ heroku config:set S3_ACCESS_KEY=<access key>
$ heroku config:set S3_SECRET_KEY=<secret key>
$ heroku config:set S3_BUCKET=<bucket name>

望各位大牛赐教,谢谢!

https://github.com/carrierwaveuploader/carrierwave/issues/2023 把 picture_uploader.rb 里的

if Rails.env.production?
  storage :fog
elsif Rails.env.development?
  storage :file
end 

上面这段代码放到carrier_wave.rb里,并且在fog_credentials的下面。

ken 回复
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      if Rails.env.production?
        storage :fog
      elsif Rails.env.development?
        storage :file
      end
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
    config.fog_directory = ENV['S3_BUCKET']
  end
end

您的意思是这样吗?

这样的话有两个问题:
1、最顶端我已经有一个 if 判断了,再把这个 if 加进来是不是有点多余,我是不是直接把 storage :fog 加进来就好; 2、把它加到 config.fog_credentials 下是报语法错误的,是不是应该放在 前一行。

如下:

if Rails.env.production?
  CarrierWave.configure do |config|
    storage :fog
    config.fog_credentials = {
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
    config.fog_directory = ENV['S3_BUCKET']
  end
end

config.fog_credentials = {
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
  if Rails.env.production?
        storage :fog
      elsif Rails.env.development?
        storage :file
      end

我猜是这样

config.fog_credentials = {
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
    storage :fog
ken 回复

修改后的文件
app/uploaders/picture_uploader.rb

class PictureUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process resize_to_limit:[400, 400]

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

config/initializers/carrier_wave.rb

if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      #  Amazon S3 的配置
      :provider => 'AWS',
      :aws_access_key_id => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
    }
    storage :fog
    config.fog_directory = ENV['S3_BUCKET']
  end
end

修改后 再次 push 还是报一样的错误

picture_uploader.rb 里不能再放 storage :file 了,或者要加上环境判断

看上面给的链接,其中有人回复https://github.com/carrierwaveuploader/carrierwave/issues/2023#issuecomment-310667421,不妨也参考下。

ken 回复

我改成了

if Rails.env.development?
    storage :file
  end

也将

require 'carrierwave/storage/fog'

加到对应文件中了
还是报错

可以留个微信或者 QQ,我加你,慢慢看。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号