I have been trying to google this question for a while and am not finding any answers.
For some reason, my app works fine when I run on localhost but not when I deploy to heroku.
I think the relevant gems/services are Heroku, CarrierWave, and possibly Devise & Fog-AWS.
rails aborted!
NameError: uninitialized constant User::AvatarUploader
/app/app/models/user.rb:6:in `<class:User>'
/app/app/models/user.rb:2:in `<top (required)>'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/dependencies/interlock.rb:12:in `block in loading'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/concurrency/share_lock.rb:149:in `exclusive'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/dependencies/interlock.rb:11:in `loading'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/inflector/methods.rb:269:in `const_get'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/inflector/methods.rb:269:in `block in constantize'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/inflector/methods.rb:267:in `each'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/inflector/methods.rb:267:in `inject'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/inflector/methods.rb:267:in `constantize'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise.rb:315:in `get'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/mapping.rb:83:in `to'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/mapping.rb:78:in `modules'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/mapping.rb:95:in `routes'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/mapping.rb:162:in `default_used_route'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/mapping.rb:72:in `initialize'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise.rb:345:in `new'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise.rb:345:in `add_mapping'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/rails/routes.rb:243:in `block in devise_for'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/rails/routes.rb:242:in `each'
/app/vendor/bundle/ruby/2.3.0/gems/devise-4.4.2/lib/devise/rails/routes.rb:242:in `devise_for'
/app/config/routes.rb:3:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.3.0/gems/actionpack-5.1.2/lib/action_dispatch/routing/route_set.rb:424:in `instance_exec'
/app/vendor/bundle/ruby/2.3.0/gems/actionpack-5.1.2/lib/action_dispatch/routing/route_set.rb:424:in `eval_block'
/app/vendor/bundle/ruby/2.3.0/gems/actionpack-5.1.2/lib/action_dispatch/routing/route_set.rb:406:in `draw'
/app/config/routes.rb:1:in `<top (required)>'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:55:in `block in load_paths'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:55:in `each'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:55:in `load_paths'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:18:in `reload!'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:41:in `block in updater'
/app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.2/lib/active_support/file_update_checker.rb:81:in `execute'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:42:in `updater'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/routes_reloader.rb:31:in `execute_if_updated'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application/finisher.rb:128:in `block in <module:Finisher>'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/initializable.rb:30:in `instance_exec'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/initializable.rb:30:in `run'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/initializable.rb:59:in `block in run_initializers'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/initializable.rb:58:in `run_initializers'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application.rb:353:in `initialize!'
/app/config/environment.rb:6:in `<top (required)>'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application.rb:329:in `require_environment!'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/application.rb:445:in `block in run_tasks_blocks'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/commands/rake/rake_command.rb:21:in `block in perform'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/commands/rake/rake_command.rb:18:in `perform'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/command.rb:46:in `invoke'
/app/vendor/bundle/ruby/2.3.0/gems/railties-5.1.2/lib/rails/commands.rb:16:in `<top (required)>'
/app/bin/rails:9:in `require'
/app/bin/rails:9:in `<main>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
Gemfile:
source 'https://rubygems.org'
gem 'rails', '5.1.2'
gem 'bcrypt', '3.1.11'
gem 'bootstrap-sass', '3.3.7'
gem 'puma', '3.9.1'
gem 'sass-rails', '5.0.6'
gem 'uglifier', '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks', '5.0.1'
gem 'jbuilder', '2.7.0'
gem 'will_paginate', '3.1.6'
gem 'bootstrap-will_paginate'
gem 'ice_cube'
gem 'chronic'
# [START omniauth]
gem 'devise'
gem "omniauth"
gem "omniauth-google-oauth2"
gem 'omniauth-google'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
# [END omniauth]
gem 'dotenv-rails'
group :development, :test do
gem 'byebug', '9.0.6', platform: :mri
gem 'factory_bot_rails'
gem 'rspec-rails'
end
group :development, :test, :production do
gem 'pg'
end
group :development do
gem 'web-console', '3.5.1'
gem 'listen', '3.0.8'
gem 'spring', '2.0.2'
gem 'spring-watcher-listen', '2.0.1'
end
group :test do
gem 'rails-controller-testing', '1.0.2'
gem 'minitest-reporters', '1.1.14'
gem 'guard', '2.13.0'
gem 'guard-minitest', '2.4.4'
gem 'rspec'
gem 'rspec-core'
gem 'rspec-rails'
end
group :production do
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
#URL Gems
gem "validate_url"
gem 'metainspector'
#Avatars
gem 'carrierwave', '~> 1.0'
gem 'rmagick', '~> 2.0'
gem "mini_magick"
gem 'fog-aws'
user.rb:
require 'carrierwave/orm/activerecord'
class User < ApplicationRecord
devise :rememberable, :trackable,
:omniauthable, omniauth_providers: %i[google_oauth2]
mount_uploader :avatar, AvatarUploader
application.rb
require 'carrierwave'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module MyApp
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1
config.assets.paths << Rails.root.join("app", "assets", "fonts")
config.autoload_paths += Dir[Rails.root.join('app', 'uploaders', '*.rb')]
carrierwave.rb:
CarrierWave.configure do |config|
# Use local storage if in development or test
if Rails.env.test? or Rails.env.cucumber?
CarrierWave.configure do |config|
config.storage = :file
config.enable_processing = false
end
end
# Use AWS storage if in production
if Rails.env.production?
CarrierWave.configure do |config|
config.storage = :fog
end
end
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: ENV['S3_KEY'], # required
aws_secret_access_key: ENV['S3_SECRET'], # required
region: 'us-east-2', # optional, defaults to 'us-east-1'
}
config.fog_directory = ENV['S3_BUCKET'] # required
config.fog_public = false # optional, defaults to true
config.fog_attributes = { cache_control: "public, max-age=315576000" } # optional, defaults to {}
end
# config/initializers/carrierwave.rb
module CarrierWave
module MiniMagick
def quality(percentage)
manipulate! do |img|
img.quality(percentage.to_s)
img = yield(img) if block_given?
img
end
end
end
end
avatar_uploader.rb:
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
#storage :file
storage :fog
process resize_to_fill: [60, 60]
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fit: [50, 50]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_whitelist
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
process :convert => 'png'
def filename
super.chomp(File.extname(super)) + '.png' if original_filename
end
end
Any ideas?
2
Answers
Ok so some changes I made to solve this issue:
config/environment.rb :
carrierwave.rb:
Note: It is important for
config.storage
to go afterconfig.fog.credentials
!Then I set
S3_KEY
S3_SECRET
in terminal withheroku config:set S3_KEY=********* S3_SECRET=*******
and it worked!
On the
application.rb
add this linerequire 'carrierwave/orm/activerecord'
fromuser.rb
, so after added this line toapplication.rb
then it will look like somethingactually, this the way which works for me after error
then updated like this.