I installed carrierwave gem in my rails app.
My uploader class
class VoiceUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
My model class
require 'carrierwave/orm/activerecord'
class PulseFeedback < ActiveRecord::Base
belongs_to :tablet
mount_uploader :voice, VoiceUploader
end
But whenever I use store method in my rails console I get this error.
2.2.0 :001 > v = VoiceUploader.new
=> #<VoiceUploader:0x000000038dc8b0 #model=nil, #mounted_as=nil>
2.2.0 :002 > v.store!("/home/raghu/Music/ajeeb.mp3")
CarrierWave::FormNotMultipart: CarrierWave::FormNotMultipart
from /home/raghu/.rvm/gems/ruby-2.2.0/gems/carrierwave-0.10.0/lib/carrierwave/uploader/cache.rb:120:in `cache!'
from /home/raghu/.rvm/gems/ruby-2.2.0/gems/carrierwave-0.10.0/lib/carrierwave/uploader/store.rb:56:in `store!'
I also don't understand why model and mounted are nil even though I have defined mounter in my model class
You should store a file, not a string
class VoiceUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads"
end
end
v = VoiceUploader.new
File.open("/home/raghu/Music/ajeeb.mp3") do |f|
v.store!(f)
end
Or try to use model for that
PulseFeedback.create({
voice: File.open("/home/raghu/Music/ajeeb.mp3")
})
Related
I have RoR project, living on heroku. I have bootsy (editor with image upload funcs) and I have cloudinary.
Ive setup uploader, cloudinary api keys and initializers (can show you, if it needed). Now, when I try to upload image in bootsy - it creates database row, and create image in cloudinary. But in js window from bootsy, there empty <img>
ruby '2.3.1'
gem 'rails', '~> 5.1.1'
gem 'bootsy'
gem 'carrierwave'
gem 'fog'
gem 'cloudinary', '~> 1.8.1'
1) uploaders/bootsy/image_uploader.rb
module Bootsy
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# storage Bootsy.storage
include Cloudinary::CarrierWave
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :large do
process :eager => true
process resize_to_fit: [
700, 700
]
end
version :medium do
process :eager => true
process resize_to_fit: [
300, 300
]
end
version :small do
process :eager => true
process resize_to_fit: [
150, 150
]
end
version :thumb do
process :eager => true
process resize_to_fit: [
150, 150
]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
end
2) initializers/bootsy.rb
Bootsy.setup do |config|
config.image_versions_available = [:small, :medium, :large, :original]
config.storage = :fog
end
3) models/article.rb
class Article < ApplicationRecord
include Bootsy::Container
mount_uploader :image, Bootsy::ImageUploader
mount_uploader :main_image, ArticleImageUploader
mount_uploader :list_image, ArticleImageUploader
end
P.S Ok, I really have no idea - I just repeat this bug in public repository. https://bitbucket.org/dekakisalove/bootsy_tes/ I will add bounty to this question as soon as it will be possible.
This problem is due to an incorrect return value the method store! of class Cloudinary::CarrierWave::Storage
To work around this problem, you can use several variants, for example:
like this in config/initializers/cloudinary_store.rb
module CloudinaryStorage
def store!(file)
super || uploader.metadata
end
end
ActiveSupport.on_load :after_initialize do
Cloudinary::CarrierWave::Storage.prepend CloudinaryStorage
end
or like this inapp/uploaders/image_uploader.rb
module Bootsy
class ImageUploader < CarrierWave::Uploader::Base
after :store, :reload_data
def reload_data(file)
model.reload
end
# etc..
video_uploader.rb
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
alias_method :extension_white_list, :extension_whitelist
def will_include_content_type
true
end
default_content_type 'video/mp4'
allowed_content_types %w(video/mpeg video/mp4 video/ogg)
end
Model.rb
class Video < ActiveRecord::Base
mount_uploader :videosub, VideoUploader
end
Parameters:
"videosub"=>#<ActionDispatch::Http::UploadedFile:0x007f87201e28 #tempfile=#<Tempfile:/tmp/RackMultipart20170509-4704-1mjrwq.mp4>, #original_filename="168C7704-4337-A870-007B2CB22519.mp4", #content_type="video/mp4
Error showing is:
Validation failed: Videosub is invalid.
And if I replace the code inside VideoUploader as:
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
alias_method :extension_white_list, :extension_whitelist
storage :fog
end
Then the file is being successfully being uploaded to S3. But in my case I need to upload the video in background and directly to S3 bypassing the server on which the app is hosted.
Please help!
Found the solution:
Earlier I was including the gem by defining the github path of the repo. Later on I just eliminated the path. And it worked.
I have a brand model
class Brand < ActiveRecord::Base
attr_accessible :activities, :attendees, :date, :description, :name, :place, :requirements_on_event, :requirements_other, :requirements_post_event, :requirements_pre_event, :target_students, :target_universities, :type, :image
mount_uploader :image, ImageUploader
end
I have the following in my brands table
t.string "image"
and here is my image_uploader.rb
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::MiniMagick
include CarrierWave::RMagick
# include ::CarrierWave::Backgrounder::Delay
# Choose what kind of storage to use for this uploader:
storage :file
#storage :fog
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
I have these in my gemfile
#Picture Upload and Storage
gem 'carrierwave'
gem 'carrierwave_backgrounder'
gem 'fog'
#gem 'aws-s3'
gem 'rmagick'
gem 'mini_magick
Now the problem is per the doc on carrierwave's github page
I try
bundle exec rails c and rails c
uploader = ImageUploader.new
I am getting this returned message in green
=> #<ImageUploader:0x007fcf2450bf68 #model=nil, #mounted_as=nil>
why is the #model=nil and #mounted_as=nil?
when I try to this
uploader.store!(/Users/judyngai/Desktop/brandspictures/circle_accupass.png)
I am getting this error
SyntaxError: (eval):2: unknown regexp options - jdyga
and if I try this
uploader.store!('/Users/judyngai/Desktop/brandspictures/circle_accupass.png')
carrierwave won't let me do it
CarrierWave::FormNotMultipart: You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.
I feel like I installed everything correctly. Its a rails 3.2.13 app. I commented out my carrierwave.rb because I am having trouble with fog and aws.
I just tried adding this to my model but still getting the same thing.
require 'carrierwave/orm/activerecord'
You should be calling store! method as below:
uploader.store!(File.open('/Users/judyngai/Desktop/brandspictures/circle_accupass.png'))
You should be passing an instance of File rather than a String. Hence, the error You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.
I've got a photo upload feature in my rails app. The app uploads direct to s3 through carrierwave via rmagick and fog. The issue I am having is when a photo is uploaded via mobile through the "take a photo option" in portrait (note this is with iphone but I believe android has the same issue). Once uploaded the image appears fine on mobile, however when viewed on desktop the image appears rotated 90 degrees.
Through my research it looks to be an issue with exif. This stackoverflow responder outlines 2 potential solutions. This gist also looks promising as well.
So far I have found a few solutions posted but none have worked. Ideally I would like the photo to be saved to s3 as a portrait, then just display the image as is.
Any suggestions are well appreciated.
Below is my code
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
include CarrierWave::RMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
include CarrierWave::MimeTypes
process :fix_exif_rotation
process :set_content_type
version :thumb do
process resize_to_fill: [200, 200]
end
def extension_white_list
%w(jpg jpeg png)
end
def fix_exif_rotation #this is my attempted solution
manipulate! do |img|
img = img.auto_orient!
end
end
end
app/models/s3_image.rb
class S3Image < ActiveRecord::Base
attr_accessible :image, :name, :user_id
mount_uploader :image, ImageUploader
belongs_to :user
def image_name
File.basename(image.path || image.filename) if image
end
class ImageWorker
include Sidekiq::Worker
def perform(id, key)
s3_image = S3Image.find(id)
s3_image.key = key
s3_image.remote_image_url = s3_image.image.direct_fog_url(with_path: true)
s3_image.save!
s3_image.update_column(:image_processed, true)
end
end
end
config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: " ... ",
aws_secret_access_key: " ... "
}
config.fog_directory = " ... "
end
btw I used this Railscast as a guide for setting up my s3 upload.
Well I got this working using fog instead or carrierwave_direct.
Below is the code that ended up working for me:
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
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
def fix_exif_rotation #this is my attempted solution
manipulate! do |img|
img.tap(&:auto_orient)
end
end
process :fix_exif_rotation
end
app/models/s3_image.rb
class S3Image < ActiveRecord::Base
attr_accessible :image, :name, :user_id, :image_cache
mount_uploader :image, ImageUploader
belongs_to :user
end
initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: " ... ",
aws_secret_access_key: " ... ",
region: 'us-west-2'
}
config.fog_directory = " ... "
end
I had a similar problem and fixed it with an approach nearly identical to yours.
# In the uploader:
def auto_orient
manipulate! do |img|
img = img.auto_orient
end
end
(Note that I am not calling auto_orient! - just auto_orient, without the bang.)
Then I have process :auto_orient as the first line of any version I create. For example:
version :square do
process :auto_orient
process :resize_to_fill => [600, 600]
end
My solution (quite similar to Sumeet) :
# painting_uploader.rb
process :right_orientation
def right_orientation
manipulate! do |img|
img.auto_orient
img
end
end
It's really important to return an image. Otherwise, you'll get an
NoMethodError (undefined method `write' for "":String):
Lando2319's answer was not working for me.
I am using RMagick.
I managed to make ImageMagick apply the correct orientation (and to reset the EXIF rotation data in order to avoid a double rotation by the viewer) by using :
def fix_exif_rotation # put this before any other process in the Carrierwave uploader
manipulate! do |img|
img.tap(&:auto_orient!)
end
The difference between my solution & Lando's is the bang (!). In my case it was absolutely necessary.
I am developing Rails 3.2.9 app and using Carrierwave as file uploader. The Carriverwave readme point out the way to get correct content_type:
Add require 'carrierwave/processing/mime_types' to an initializer or your uploader(s).
Add include CarrierWave::MimeTypes to your uploader.
Add process :set_content_type to your uploader(s).
Base on this, My uploader is below:
# encoding: utf-8
require 'carrierwave/processing/mime_types'
class AttachmentUploader < CarrierWave::Uploader::Base
include CarrierWave::MimeTypes
storage :file
def store_dir
"#{base_store_dir}/#{model.id}"
end
process :set_content_type
end
In my model, mount the uploader as file:
mount_uploader :file, AttachmentUploader
However, I always got content_type nil after upload file:
1.9.3-p327 :013 > a.file.class
=> AttachmentUploader
1.9.3-p327 :010 > a.file.file
=> #<CarrierWave::SanitizedFile:0x00000004046330 #file="uploads/course/000/000/026/attachment_file/6/myIcon.png", #original_filename=nil, #content_type=nil>
Any suggestion? Thanks.
PS: I already added gem "mime-types", "~> 1.19" in my Gemfile.
You will need to follow the instructions laid out here: https://github.com/carrierwaveuploader/carrierwave#setting-the-content-type
Add the mime-types gem, then setup your uploader file like so
require 'carrierwave/processing/mime_types'
class MyUploader < CarrierWave::Uploader::Base
include CarrierWave::MimeTypes
process :set_content_type
end
Had the same problem tried this in my Model file where I mounted the Uploader
before_save :set_mime_type
def set_mime_type
self.mimetype = Mime::Type.lookup_by_extension(File.extname(self.cf_filename.to_s)[1..-1])
end
Note: You need to have a mimetype field in the table
I just hit the exact same problem and couldn't find an easy fix.
My workaround was to add a content_type column to the model and set it in the create/update process with
#model.content_type = params[:file_upload][:attachment].content_type
This works, though hopefully the issue gets fixed.