I have this error trying to upload images to aws bucket.
no implicit conversion of nil into String
I am currently just using an uploading class and an initializer file.
initializers/carrierwave.rb
Carrierwave.configure do |config|
config.storage = :aws
config.aws_bucket = 'larfs'
config.aws_acl = :public_read
config.assets_host = ''
config.aws_authenticated_url_expiration = 60 * 6 * 24 * 365
config.aws_credentials = {
access_key_id: 132abc,
secret_access_key: 123abc
}
end
videouploader class, (used in this instance just for images)
class VideoUploader < 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
storage :aws
# 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
# # 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)
# process r
# end
# Create different versions of your uploaded files:
version :thumb do
# process :scale => [50, 50]
process :resize_to_fill => [90, 90]
end
version :index do
process :resize_to_fill => [200, 200]
end
version :medium do
# process :scale => [150, 170]
process :resize_to_fit => [200, 300]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%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.
# def filename
# "something.jpg" if original_filename
# end
end
Add in the Gemfile:-
gem 'carrierwave'
gem 'rmagick'
gem 'fog'
gem 'carrierwave_direct'
In initializers/carrierwave.rb:-
CarrierWave.configure do |config|
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: '132abc',
aws_secret_access_key: '123abc'
}
config.fog_directory = 'larfs'
end
In videouploader class:-
class VideoUploader < 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
#storage :aws
# 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
# # 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)
# process r
# end
# Create different versions of your uploaded files:
version :thumb do
# process :scale => [50, 50]
process :resize_to_fill => [90, 90]
end
version :index do
process :resize_to_fill => [200, 200]
end
version :medium do
# process :scale => [150, 170]
process :resize_to_fit => [200, 300]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%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.
# def filename
# "something.jpg" if original_filename
# end
end
I spent a LOT of time trying to get carrierwave and fog to work together to upload images to AWS.
In the end, it was as simple as moving away from Fog and using the carrierwave-aws gem - https://github.com/sorentwo/carrierwave-aws
Documentation was pretty easy to follow.
Fog was way more than I needed for a simple image upload and carrierwave-aws just worked.
Lots of benefits to switch unless you're beholden to Fog for a specific need.
Related
I'm working on a web application that uses CarrierWave and MiniMagick to handle image uploads for account profile pictures. Right now my AvatarUploader class looks like this
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# In the uploader:
def auto_orient
manipulate! do |img|
img = img.auto_orient
end
end
# Choose what kind of storage to use for this uploader:
# storage :file
# storage :fog
# 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
ActionController::Base.helpers.asset_path('default_avatar.png')
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 :auto_orient
process :resize_to_fill => [200, 200]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %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.
# def filename
# "something.jpg" if original_filename
# end
end
and the field for handling avatar upload in the form looks like this
.row
- if f.object.avatar.present?
.field
= image_tag f.object.avatar.url
= f.input :avatar, label: f.object.avatar.present? ? 'Replace Avatar' : 'Avatar'
This all works great on the desktop version of my site but when a user uploads a profile pic they take from their mobile phone it gets turned sideways 90 degrees and I can't figure out why. I thought adding the auto_orient code from this question would fix the problem but it did not
credit: #lando2319
exif image rotation issue using carrierwave and rmagick to upload to s3
try changing your auto_orient method to this:
def auto_orient
manipulate! do |img|
img.tap(&:auto_orient!) #try with and without the ! here.
end
end
Figured it out.
process :auto_orient
Needs to be called outside the version: thumb do loop
Full code
# encoding: utf-8
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# In the uploader:
def auto_orient
manipulate! do |img|
img.auto_orient
img
end
end
# Choose what kind of storage to use for this uploader:
# storage :file
# storage :fog
# 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
ActionController::Base.helpers.asset_path('default_avatar.png')
end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
process :resize_to_fit => [400, 400]
process :auto_orient
# Create different versions of your uploaded files:
version :thumb do
process :auto_orient
process :resize_to_fit => [200, 200]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %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.
# def filename
# "something.jpg" if original_filename
# end
end
I'm upgrading my project from Rails 2 with attachment_fu to Rails 3 with carrierwave. I have an existing database and file directory with images that were uploaded using attachment_fu. Problem is that in attachment_fu, images were uploaded with the image version (thumb, small, medium, etc) appended to the back of the filename (my_image_small.jpg) while in carrierwave, the default is the other way around (small_my_image.jpg). Where in carrierwave would I change this?
here's my FileUploader:
# encoding: utf-8
class FileUploader < CarrierWave::Uploader::Base
#include UploaderFu
# Include RMagick or MiniMagick support:
SMALL_WIDTH = 101
MEDIUM_WIDTH = 223
LARGE_WIDTH = 345
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
# include Sprockets::Helpers::RailsHelper
# include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# 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}"
"#{Rails.root}/public/file_uploads/#{("%08d" % model.id).scan(/..../).join('/')}"
#{}"#{Rails.root}/public/file_uploads/"
end
version :small do
process :resize_to_fit => [SMALL_WIDTH, 10000]
end
version :medium do
process :resize_to_fit => [MEDIUM_WIDTH, 10000]
end
version :large do
process :resize_to_fit => [LARGE_WIDTH, 10000]
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # 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 :scale => [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_white_list
%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.
# def filename
# "something.jpg" if original_filename
# end
end
To override the filename convention for a specific version, you can define a full_filename method in the version block:
version :small do
def full_filename(for_file)
[super(for_file), version_name].compact.join('_')
end
process :resize_to_fit => [SMALL_WIDTH, 10000]
end
This method is simply a rewrite of the existing full_filename method in the CarrierWave source code (see versions.rb).
You'll need to override this on every version, however. Instead, you might want to change CarrierWave's default behavior by patching the Versions module. You can add this an an initializer:
module CarrierWave
module Uploader
module Versions
def full_filename(for_file)
[super(for_file), version_name].compact.join('_')
end
end
end
end
Update:
To correct the issue with the file extension, you can use Rake's pathmap function to parse the filename:
require 'rake'
def full_filename(for_file)
filename = for_file.pathmap("%n")
extension = for_file.pathmap("%x")
[filename, version_name].compact.join('_') + extension
end
Just in case anyone wants to know how I figured it out, I looked into the gem code and found out the filename was being set by def full_filename, so in my FileUploader I rewrote the method so that it would overwrite the behavior.
def full_filename (for_file = model.filename.file)
"#{for_file[/(.+)\./][$1]}_#{version_name}.#{for_file[/\.(.+)/][$1]}"
end
I have setup carrierwave backgrounder locally along with sidekiq and sidekiq web. I can see jobs being added to the sidekiq Enqueued but they are never running. What would prevent them from executing?
Setup:
Rails 3.2.11
Unicorn 4.6.1
Sidekiq 2.7.5
carrierwave 0.8.0
carrierwave_backgrounder 0.2.0
Config for backgrounder.
CarrierWave::Backgrounder.configure do |c|
c.backend :sidekiq, queue: :carrierwave
end
Model
class EntryImage < ActiveRecord::Base
attr_accessible :alt, :image_path
belongs_to :imageable, :polymorphic => true
validates :image_path, presence: true
mount_uploader :image_path, ImageUploader
process_in_background :image_path
end
Uploader
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
include ::CarrierWave::Backgrounder::Delay
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
# include Sprockets::Helpers::RailsHelper
# include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
if Rails.env.test?
storage :file
else
storage :fog
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
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # 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 :scale => [50, 50]
# end
process :resize_and_pad => [1280, 720, "#111111"]
version :thumb do
process :resize_and_pad => [384,216, "#111111"]
end
version :thumblarge do
process :resize_and_pad => [640,360, "#111111"]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%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.
# def filename
# "something.jpg" if original_filename
# end
end
Checking Registered workers comes back empty
1.9.3p194 :006 > Sidekiq::Client.registered_workers
=> []
config/sidekiq.yml
:concurrency: 1
config/initializer/sidekiq.rb
require 'sidekiq'
Sidekiq.configure_client do |config|
config.redis = { :size => 1 }
end
Sidekiq.configure_server do |config|
# The config.redis is calculated by the
# concurrency value so you do not need to
# specify this. For this demo I do
# show it to understand the numbers
config.redis = { :size => 3 }
end
I have started sidekiq from the commandline in a few ways also
bundle exec sidekiq -q high,5 default
bundle exec sidekiq
Thank you for the help :)
Ok I was starting sidekiq incorrectly. -q needed to be set to the queue name.
I am using CarrierWave gem to upload images. The problem is, if anyone opens the network terminal in the browser they can easily find out the name of the image. So I just want to avoid it by renaming the image file while deploying to the server. So I can use filename. But the problem is here. The "filename" method is not at all executing in my code. Here is my uploader file.
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
# "/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_limit => [100, 100]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%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.
# def filename
# "something.jpg" if original_filename
# end
def filename
logger.info "*******inside filename method"
end
end
Thanks in advance
I'm having issues setting a default image in my carrierwave uploader. It seems to be appending a weird class to the front of the URL but not rendering the image. See my code below.
Helper
# encoding: utf-8
class UserpicUploader < CarrierWave::Uploader::Base
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprokets helpers for Rails 3.1+ asset pipeline compatibility:
# include Sprockets::Helpers::RailsHelper
# include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# 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
# Process files as they are uploaded:
version :normal do
process :resize_to_fill => [162, 163]
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# For Rails 3.1+ asset pipeline compatibility:
# asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
"/images/fallback/" + [normal, "profile_default_pic.png"].compact.join('_')
end
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :scale => [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_white_list
%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.
def filename
if original_filename
#name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{#name}.#{file.extension}"
end
end
end
EDIT...
Here is the edited code that worked. I had to put the image in public/fallback instead of Assets/images/fallback.
# encoding: utf-8
class UserpicUploader < CarrierWave::Uploader::Base
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprokets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# 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
# Process files as they are uploaded:
version :normal do
process :resize_to_fill => [162, 163]
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# For Rails 3.1+ asset pipeline compatibility:
asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
# "/fallback/" + [normal, "profile_default_pic.png"].compact.join('_')
end
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :scale => [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_white_list
%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.
def filename
if original_filename
#name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{#name}.#{file.extension}"
end
end
end
Ok I got it working this is what I was missing...
The default folder had to be in the public/ folder not in assets/images
I had to add the following lines to the uploader class:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
I had to change the default_url to the following:
asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
In Rails 4.1.* you can just specify the filename in the default_url method
def default_url
"default.png"
end
In this case the default.png should be in /app/assets/images folder
edit the uploader class :
def default_url
"/images/fallback/" + [version_name,"default.png"].compact.join('_')
end
and then copy the default picture in /images/fallback/default.png