I want to upload multiple images to cloudinary by association of a carrierwave active record. How can I do this in a seeds file, using an array of remote urls?
Ive read countless articles how to use carrierwave/cloudinary helper tags to target an image upload within an html form, but nothing on doing this directly within code, any ideas?
That's not so hard to do at all.
So what I did:
# Gemfile
gem 'cloudinary'
gem 'carrierwave'
#config/cloudinary.yml
development:
cloud_name: "carrierwave-example"
api_key: "YOUR CLOUDINARY CREDENTIALS"
api_secret: "YOUR CLOUDINARY CREDENTIALS"
# in your uploader
class ImageUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave #include cloudinary lib
# storage :file - comment this out
# def store_dir - comment this too
# "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
# end
end
# You model, that uses uploader
class Picture < ActiveRecord::Base
mount_uploader :image, ImageUploader
end
After writting this simple staff you can create Pictures, that will store images in clodinary like this:
Picture.create(image: "/path/to/image")
or if you have remote links of images, U just itterate through them
["http://image1.jpg","http://image2.jpg","http://image3.jpg"].each do |link|
Picture.create(remote_image_url: link)
end
Just remember to use remote_#{your_column_name}_url if you have remote link
Related
Any idea how to migrate a running project using Refile to the new rails's Active Storage?
Anyone knows any tutorial/guide about how to do that?
Thanks,
Patrick
I wrote a short post about it here which explains the process in detail:
https://dev.to/mtrolle/migrating-from-refile-to-activestorage-2dfp
Historically I hosted my Refile attached files in AWS S3, so what I did was refactoring all my code to use ActiveStorage instead. This primarily involved updating my model and views to use ActiveStorage syntax.
Then I removed the Refile gem and replaced it with ActiveStorage required gems like the image_processing gem and the aws-sdk-s3 gem.
Finally I created a Rails DB migration file to handle the actual migration of existing files. Here I looped through all records in my model with a Refile attachment to find their respective file in AWS S3, download it and then attach it to the model again using the ActiveStorage attachment.
Once the files were moved I could remove the legacy Refile database fields:
require 'mini_magick' # included by the image_processing gem
require 'aws-sdk-s3' # included by the aws-sdk-s3 gem
class User < ActiveRecord::Base
has_one_attached :avatar
end
class MovingFromRefileToActiveStorage < ActiveRecord::Migration[6.0]
def up
puts 'Connecting to AWS S3'
s3_client = Aws::S3::Client.new(
access_key_id: ENV['AWS_S3_ACCESS_KEY'],
secret_access_key: ENV['AWS_S3_SECRET'],
region: ENV['AWS_S3_REGION']
)
puts 'Migrating user avatar images from Refile to ActiveStorage'
User.where.not(avatar_id: nil).find_each do |user|
tmp_file = Tempfile.new
# Read S3 object to our tmp_file
s3_client.get_object(
response_target: tmp_file.path,
bucket: ENV['AWS_S3_BUCKET'],
key: "store/#{user.avatar_id}"
)
# Find content_type of S3 file using ImageMagick
# If you've been smart enough to save :avatar_content_type with Refile, you can use this value instead
content_type = MiniMagick::Image.new(tmp_file.path).mime_type
# Attach tmp file to our User as an ActiveStorage attachment
user.avatar.attach(
io: tmp_file,
filename: "avatar.#{content_type.split('/').last}",
content_type: content_type
)
if user.avatar.attached?
user.save # Save our changes to the user
puts "- migrated #{user.try(:name)}'s avatar image."
else
puts "- \e[31mFailed to migrate the avatar image for user ##{user.id} with Refile id #{user.avatar_id}\e[0m"
end
tmp_file.close
end
# Now remove the actual Refile column
remove_column :users, :avatar_id, :string
# If you've created other Refile fields like *_content_type, you can safely remove those as well
# remove_column :users, :avatar_content_type, :string
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
I want to upload a zip file contains documents and after uploading it to server I want to extract those on server.
I have used Carrierwave Gem to upload zip file code is below for that :
class AttachmentUploader < 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
# 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 extension_white_list
%w(zip)
#%w(pdf doc htm html docx)
end
end
No what I want to know that which Gem can help me to achieve the extraction part and where that code will be placed in this uploader class or anywhere else.. I'm very new to this rails stuff so if this question require anything more pls do let me know.
I have the client upload an image directly to S3 with javascript and have designed the url to be exactly what it would be if carrierwave was uploading it (by using a unique_id that I pass to the create method). Once the image is uploaded, I want to send an AJAX request to create the record, and then process the image using carrierwave, but I don't need carrierwave to handle the upload, just process the versions.
I have this typical carrierwave setup using the fog gem for s3 storage:
class Picture < ActiveRecord::Base
mount_uploader :image, ImageUploader
# . . .
end
and this:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :fog
def store_dir
"uploads/picture/#{model.unique_id}"
end
version :large do
resize_to_limit(600, 600)
end
# . . .
end
But I can't figure out how to create a new Picture without carrierwave wanting to handle the upload.
I have tried setting Picture.image to the filename but it becomes nil:
>> Picture.create(image: params[:filename], unique_id: params[:unique_id])
=> #<Picture id: 96, image: nil, ... >
I have also tried getting the image by using carrierwave's "Uploading files from a remote location" feature:
class PicturesController < ApplicationController
def create
#picture = Picture.create(
remote_image_url: params[:url],
unique_id: params[:unique_id]
)
# . . .
end
# . . .
end
That works eventually, but it is a lot of extra downloading and uploading and feels wrong.
How do I create the Picture without carrierwave getting involved, and then have carrierwave process the image versions?
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 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.