Paperclip stores original images in "original" folder. Is there a way to resize the original images? I want to make the originals smaller in order to save the disc space.
So, for example, if visitor uploads a photo with 2592x1936 I want to store it as 1024x1024, the same way we set the dimensions for :thumb images in :styles
Update (solved)
I found out how to resize original images automatically on upload. One just needs to add :original to styles:
class MyModel < ActiveRecord::Base
has_attached_file :photo,
:styles => { :original => "1024x1024>", :thumb => "150x150>" }
end
I'm not sure paperclip does resizing by itself. You might have to look at Rmagick to get this done. I would try to get RMagick going (or minimagick) and then use a before_save callback to execute a :resize method that you write that tells RMagic to resize the image. Your method might look like:
class Image < ActiveRecord::Base
belongs_to :profile
before_save :resize
def resize
self.image = self.image.resize "1024x1024"
end
end
or
class Image < ActiveRecord::Base
belongs_to :profile
before_save do
self.image = self.image.resize "1024x1024"
end
end
Related
I am using Rails 3 and carrierwave gem.
My problem is the next:
I am coding a wizard form with multiple models and relations. So My application has products which has many images through Image model (Its has been mounted with carrierwave).
Because the form has many steps I want save temporaly the images with cache option in CarrierWave. then i last step i want recover the images and load my product. So I create a model called TempData which save temporaly data (In this case cache_name), a type_identifier and a mark can_be_deleted.
For example these are my models:
Product Model:
class Product < ActiveRecord::Base
has_many :images, :as => :imageable, :dependent => :destroy
def save_images_in_temporal_folder(images_attributes)
begin
uploader = ImageUploader.new
images_attributes.to_hash.each do |image|
uploader.cache!(image[1]['filename'])
TempData.create(:data => uploader.cache_name, :can_deleted => false, :type_name => TempDataType.product_image_upload_to_words)
end
rescue
end
end
def load_images_from_temporal_folder
begin
uploader = ImageUploader.new
tmp_images = []
TempData.find_all_by_can_deleted_and_type_name(false, TempDataType.product_image_upload_to_words).map(&:data).each do |cache_name|
tmp_images << uploader.retrieve_from_cache!(cache_name)
end
tmp_images
rescue
end
end
end
Image model
class Image < ActiveRecord::Base
attr_accessible :imageable_type, :imageable_id, :filename
belongs_to :imageable, :polymorphic => true
mount_uploader :filename, ImageUploader
#validates :filename, :presence => true
end
My ImageUploader:
class ImageUploader < CarrierWave::Uploader::Base
configure do |config|
config.remove_previously_stored_files_after_update = false
end
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def self.store_dir_for_file(model, mounted, filename, version = "")
filename = "#{version}_#{filename}" unless version.blank?
"uploads/#{model.class.to_s.underscore}/#{mounted}/#{model.id}/#{filename}"
end
process :resize_to_limit => [200, 300]
version :thumb do
process :resize_to_limit => [50, 50]
end
version :big do
process :resize_to_limit => [400, 400]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
So How i save/cache the images with model and mount information?. How retrieve the cache and load my product with images in cache?
Thanks in advance. Sorry for my english and if you need more information comment this post.
View the next link:
CarrierWave with ActiveResource
Also I create a model which storage temporal data. Here I save the cache_name of carrierwave. When i save the product mark these register as can_be_deleted. Then I write a task which delete these registers and clean Carrierwave cache files.
I have a scenario where i am uploading files dynamically using ajax remotipart, then later i assign those uploaded files to any model. I have such settings in uploader.
class DocumentUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.pluralize.underscore}/#{model.documentable_type.to_s.pluralize.underscore}/#{model.documentable_id}"
end
def extension_white_list
%w(doc pdf docx xls xlsx)
end
end
class Document < ActiveRecord::Base
mount_uploader :document, DocumentUploader
belongs_to :documentable, :polymorphic => true
validates :document, :presence => true
validates :description, :presence => true
end
class Post < ActiveRecord::Base
has_many :documents, :as=>:documentable
end
When i upload a document without providing documentable source, it uploads the files to /uploads/documents/uploaded_file.doc
But when i assign that document to some other model like
#post = Post.first
#post.documents << Document.last
#post.save
It save the record correctly and when get url of the file like #post.documents.first.document.url it gave url like this /uploads/documents/posts/10212/uploaded_file.doc where the file was not available.
How can i handle such assignment of pre-existing uploads?
I came here while googling and thought some people might help this piece of code I'm using in a controller to re-assign a file (here it's an image) to another model which is handled with CarrierWave:
def create
temporary_image = TemporaryImage.find(params[:temporary_image][:id])
#player = Player.new(params[:player])
#player.image = File.open(temporary_image.image.current_path)
# now you can handle #player.image as if it was
# originally assigned by CarrierWave
end
where
class Player < ActiveRecord::Base
attr_accessible :image
mount_uploader :image, PlayerImageUploader
end
and
class TemporaryImage < ActiveRecord::Base
attr_accessible :image
mount_uploader :image, TemporaryImageUploader
end
I'm using this in conjunction with an ajax fileupload (stored via TemporaryImage) where the image is immediately presented and can then be cropped. After cropping it is stored within Player.
I solved the issue by doing lot of hit and trail. but finally solved.
class Document < ActiveRecord::Base
mount_uploader :document, DocumentUploader
belongs_to :documentable, :polymorphic => true
validates :document, :presence => true
validates :description, :presence => true
after_update :relocate_files
def relocate_files
src_file = Rails.root.join("public", "uploads", "documents", document.url.split("/").last)
dst_file = Rails.root.join("public", "uploads", "documents", documentable_type.pluralize.underscore, documentable_id.to_s, document.url.split("/").last)
unless FileTest.exists?(dst_file)
FileUtils.mkdir_p(File.dirname(dst_file))
FileUtils.mv(src_file, dst_file)
end
end
end
I have a polymorhpic model as follows:
class Upload < ActiveRecord::Base
belongs_to :uploadable, :polymorphic => true
has_attached_file :photo
end
class Message < ActiveRecord::Base
has_one :upload, :as => :uploadable, :dependent => :destroy
end
The user uploads a photo in a fancy box iframe using the ajax hack with the jquery-file-upload plugin.
The uploaded photo is saved in the uploads table without uploadable_id or uploadable_type as I don't have the parent Message yet.
How can I update the Upload model with the Message id and type when I save the Message?
You can try this:
#message = Message.new(params[:message])
#message.upload = #upload
#message.save
I am trying to follow the tutorial Dynamic multiple image uploads with Ruby on Rails that creates a new model for photos and will associate them with another model. After copying and pasting all the code I'm getting an "AssociationTypeMismatch" error as follows.
ActiveRecord::AssociationTypeMismatch in AdminForksController#update
Photo(#2176152540) expected, got Array(#2148417160)
app/controllers/admin_forks_controller.rb:23:in `update'
{ "commit"=>"update",
"fork"=>{"position"=>"",
"name"=>"FORK",
"brand"=>"",
"photos"=>{"data"=>#<ActionDispatch::Http::UploadedFile:0x103634328 #headers="Content-
Disposition: form-data; name=\"fork[photos][data]\"; filename=\"marty.jpg\"\r\nContent-Type:
image/jpeg\r\n", #tempfile=#<File:/var/folders/cZ/cZVO8X55FeynZw5cHRz1UE+++TI
/-Tmp/RackMultipart20110716-18721-16ttjsd-0>, #content_type="image/jpeg",
#original_filename="marty.jpg">},
"authenticity_token"=>"iSzZxyzTe/LDLIf4cQiYBGLIk96INnKCP3SC5b5MXHw=",
"utf8"=>"?",
"id"=>"7"}
My forks model looks like this:
class Fork < ActiveRecord::Base
has_many :photos
accepts_nested_attributes_for :photos, :allow_destroy => true
end
And my photos model looks like this:
class Photo < ActiveRecord::Base
belongs_to :fork
has_attached_file :data
end
It looks like :photos is getting passed as an array, and :fork is expecting it. How do I resolve this issue?
Update
The issue was resolved (see the answer). However, how do the two variables, :fork and #fork, differ?
The problem was solved. In my for_for I was using :fork instead of #fork.
I've just started using Paperclip today and am having issues getting images to render. After some wrangling the photos are saving in the correct directory but there is a routing/rendering error:
ActionController::RoutingError (No route matches "/public/system/products/19/original/puppies-3.jpg")
However, the images are definitely saving in the correct directory. This is what's in my product model:
class Product < ActiveRecord::Base
validates :title, :presence => true
validates :description, :presence => true
validates :category, :presence => true
validates_attachment_presence :photo
validates_attachment_size :photo, :less_than => 5.megabytes
attr_accessible :photo, :photo_file_name, :photo_content_type, :photo_file_size, :photo_updated_at
attr_accessible :title, :description, :category, :price
has_attached_file :photo, :styles => { :small => "150x150>", :large => "400x400>" },
:path => ":rails_root/public/system/products/:id/:style/:basename.:extension",
:url => "/system/products/:id/:style/:basename.:extension"
end
This is in my view:
<%= image_tag #product.photo.url %>
At the moment it's simply returning the image basename instead of the image itself, any thoughts? Products is available as a resource in routes.rb, but do I need to explicitly make photos available also somehow? I'm also fairly new to Rails so struggling a little bit...
Are you sure that product with that id has a image attached? I think some of your products dont have images attached but u still looking for them. Maybe try to set a default_url. Something like this:
has_attached_file :photo, :default_url => "/images/missing.png"
This will show that image set in default_url for the products what dont have images attached.
It's ok, I've fixed it. I had left a field in my form which was naming the photo_file_name from when I couldn't get the files to save and was trying to manually override it to get it to work (face-palm). It's amazing how much clarity comes from a few hours sleep.