ruby-on-rails-4herokuamazon-s3carrierwavefog

CarrierWave url nil after upgrading from Rails 3 to Rails 4


While upgrading our app from Rails 3.2.22 to Rails 4.2.11, several CarrierWave methods that worked prior to the upgrade now return nil, such as .url and .file. We are hosting our assets on AWS S3 and our app is hosted on Heroku. Strangely, the images work as expected in our dev environment.

CarrierWave 1.3.1 (upgraded from 0.11.2)

Rails 4.2.11, upgraded from 3.2.22

Ruby 2.2.5

fog-aws 3.3.0

So far I have tried changing around the carrierwave config, and playing around with different methods in the rails console and comparing the results in development with production.

Gemfile

source 'https://rubygems.org'
ruby '2.2.5'

gem 'rails', '4.2.11'

gem 'puma'
gem 'pg', '0.15.1'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'rack-cors'
gem 'sprockets_uglifier_with_source_maps'
gem 'carrierwave'
gem 'mini_magick', '3.6.0'
gem 'paper_trail', '>= 4.0'
gem 'fog-aws'
gem 'aws-sdk-s3', '~> 1'
gem 'identity_cache', '>= 0.2'
gem 'memcachier'
gem 'dalli'
gem 'connection_pool'
gem 'active_model_serializers', '>= 0.10'
gem 'formtastic', '~> 3.1.0'
gem 'sprockets-rails', require: 'sprockets/railtie'
gem 'sprockets-image_compressor'
gem 'actionpack-action_caching'
gem 'sass-rails', '5.0.6'
gem 'uglifier', '2.5.0'
gem 'compass-rails'
gem 'sprite-factory', '1.5.3'
gem 'responders', '~> 2.0'

group :development do
  gem 'rack-mini-profiler'
  gem 'rmagick', '2.13.2'
end

carrierwave.rb


CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
      provider: ENV['FOG_PROVIDER'],
      aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
      region: ENV['FOG_REGION'],
      endpoint: ENV['FOG_HOST']
    }
  if Rails.env.production?
    config.storage = :fog
    config.fog_directory = ENV['FOG_DIRECTORY']
    config.fog_public = false
    config.fog_authenticated_url_expiration = 1800
  else
    config.asset_host = "#{ENV['FOG_HOST']}"
    config.storage = :file
    config.enable_processing = false if Rails.env.test?
  end
end
art_uploader.rb

# encoding: utf-8

class ArtUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  version :thumbnail do
    process resize_to_fill: [100, 100]
  end

  # 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

  # Add a white list of extensions which are allowed to be uploaded.
  def extension_white_list
    %w(jpg jpeg png)
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  def default_url
    if model.has_fallback_art?
      version_name == :thumbnail  
      model.song.artist.photo.small_thumb.url : 
      model.song.artist.photo.album_art.url
    end
  end

end

I expect to be able to return the asset path from S3 when I enter art.url

In development I get art.url => "https://qa-marmosetmusic-com.s3.amazonaws.com/uploads/artist/photo/173/af2ac015-1d44-4481-b5d6-5bf5cb8c0e23.jpg"

However in prodution art.url => nil.

When I enter art in the development console, it returns this object:

=> #<ArtUploader::Uploader70128841541160:0x007f904c7c88f8
 @cache_id=nil,
 @file=
  #<CarrierWave::SanitizedFile:0x007f904c1ffd68
   @content=nil,
   @content_type=nil,
   @file=
    "/Users/ekingan/dev/marmoset/public/uploads/album/art/3540/thumbnail_Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
   @original_filename=nil>,
 @filename=nil,
 @format=nil,
 @model=
  #<Album:0x007f904a0417a8
   id: 3540,
   title: "Your Heart",
   art: "Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
   state: "active",
   description: "",
   created_at: Tue, 27 Nov 2018 12:50:14 PST -08:00,
   updated_at: Tue, 27 Nov 2018 12:50:14 PST -08:00>,
 @mounted_as=:art,
 @parent_version=
  #<ArtUploader:0x007f904c7c9618
   @cache_id=nil,
   @file=
    #<CarrierWave::SanitizedFile:0x007f904c7c8948
     @content=nil,
     @content_type=nil,
     @file="/Users/ekingan/dev/marmoset/public/uploads/album/art/3540/Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
     @original_filename=nil>,
   @filename=nil,
   @format=nil,
   @model=
    #<Album:0x007f904a0417a8
     id: 3540,
     title: "Your Heart",
     art: "Evan_Andree_Your_Heart_Album_Artwork_1_3000x3000.jpg",
     state: "active",
     description: "",
     created_at: Tue, 27 Nov 2018 12:50:14 PST -08:00,
     updated_at: Tue, 27 Nov 2018 12:50:14 PST -08:00>,
   @mounted_as=:art,
   @storage=#<CarrierWave::Storage::File:0x007f904c7c9118 @cache_called=nil, @uploader=#<ArtUploader:0x007f904c7c9618 ...>>,
   @versions={:thumbnail=>#<ArtUploader::Uploader70128841541160:0x007f904c7c88f8 ...>}>,
 @storage=
  #<CarrierWave::Storage::File:0x007f904c7c86f0
   @cache_called=nil,
   @uploader=#<ArtUploader::Uploader70128841541160:0x007f904c7c88f8 ...>>,
 @versions={}>

When I enter the same in production it returns:

#<ArtUploader::Uploader6168740:0x000000072781c8 @model=#<Album id: 2008, title: "Vektlaus", art: "Daniel+Kvammen+-+Vektlaus.jpg", state: "active", description: nil, created_at: "2017-05-19 18:40:43", updated_at: "2017-07-26 16:51:17">, @mounted_as=:art, @file=nil, @filename=nil, @cache_id=nil, @versions={}, @format=nil, @parent_version=#<ArtUploader:0x00000007278d30 @model=#<Album id: 2008, title: "Vektlaus", art: "Daniel+Kvammen+-+Vektlaus.jpg", state: "active", description: nil, created_at: "2017-05-19 18:40:43", updated_at: "2017-07-26 16:51:17">, @mounted_as=:art, @file=nil, @filename=nil, @cache_id=nil, @versions={:thumbnail=>#<ArtUploader::Uploader6168740:0x000000072781c8 ...>}, @format=nil, @storage=#<CarrierWave::Storage::Fog:0x000000072786f0 @uploader=#<ArtUploader:0x00000007278d30 ...>>>, @storage=#<CarrierWave::Storage::Fog:0x00000007267300 @uploader=#<ArtUploader::Uploader6168740:0x000000072781c8 ...>>>

I would love to hear any suggestions. Thanks!


Solution

  • We resolved this!

    We had a file in carrierwave/storage called fog.rb that was overriding the gem behavior and causing this issue. Removing that file allowed everything to work as intended.