Carrierwave upload - image or video - carrierwave

I have found this link that explains how not to make thumbnails if the upload is not a video.
But how can I check, afterwards, if the saved file IS or IS NOT an image ? (In my case, I can store either images or videos), by calling a method on the model that holds the uploader ? DO I need some sort of callback in is_image?(new_file) that will set a field on the model ?
I'd like to be able to call #model.is_image?or #model.iI would bes_video? or maybe even something like case #model.type; when :video ; ...

I have added a callback to set an attribute on the model that holds the uploader
# uploader/my_uploader.rb
...
def image?(new_file)
if new_file.content_type.include? 'image'
model.image = true
true
else
false
end
end
# models/my_model.rb (mongoid)
...
field :image, type: Boolean
mount_uploader MyUploader
# View
#my_model.image?

Related

Carrierwave object.url VS object.image_url

In my Rails 5 app I am using Carrierwave to upload images.
I have to model that uses the same uploader:
account.rb:
mount_uploader :logo, ImageUploader
image.rb:
mount_uploader :image, ImageUploader
This uploads the file to:
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
The strange this now is that I can use:
#account.logo&.url(:thumb) // works!
#account.logo&.image_url(:thumb) // error!
But on the image model (one product has many images):
#product.images.first&.image_url(:thumb) // works!
#product.images.first&.url(:thumb) // error!
So in the first case I have to use .url and in the second one .image_url
An I have no idea why...any help?
The instance method image_url is defined dynamically based on the column that is passed to mount_uploader and simply calls url on the column. The definition looks like this...
def #{column}_url(*args)
#{column}.url(*args)
end
So, I would suspect that logo_url would work on #account (although I have not tested this)
source

upload image to multiple models in rails

I am using carrierwave and Minimagick gem to upload an attachment to S3. Now I want to save the some.pdf in two models(ie, assignment, and message). I give the same parameters in attachment field to save in two tables. But the second table attachment saves blurry. First one gets clear view of attachment.
My controller codes like,
#assignment = Assignment.new(assignment_params)
#message = Message.new
begin
Message.transaction do
asign_att = params[:assignment][:attachment]
#assignment.save!
#message.attachment = asign_att
#message.save!
end
end
My model has,
(in attachment.rb) mount_uploader :attachment, AttachmentUploader
(in message.rb) mount_uploader :attachment, ImageUploader
I want to save same file into two models with clear view. What I want to do? Thanks in advance.
Check in your second table uploader file if you have specified any version or something like that.
With version you can create clones of attachment in different resolutions like this.
version :thumb do
process resize_to_fit 50, 50
end
I would use a callback to do this, something like:
after_commit :assign_to_models
def assign_to_models
...
end
IMHO, I would create an model that has all the carrierwave attachements, and have it belongs both to message and attachement.
I hope this helps

creating an alias_attribute for a paperclip image in Rails

I'm currently building an app which has a model Post. I'm using the paperclip gem to upload images, and everything is going well.
class Post < ActiveRecord::Base
has_attached_file :headerimage, styles: {banner => "400x300#"}
end
As you can see by my class above, if I were to get a Post object, I could get the banner image with the following in my view:
image = Post.first.headerimage(:banner)
Alias
However, in my app, it must have the image attribute image refer to the thumbnail image. So, in my models class, I wrote
class Post < ActiveRecord::Base
has_attached_file :headerimage, styles: {banner => "400x300#"}
alias_attribute :image, :headerimage
end
which allows me to get an image by calling the following:
image = Post.first.image
This is what I want - however, it gets the original image from paperclip, so it is equivalent to writing the following:
image = Post.first.headerimage instead of image = Post.first.headerimage(:banner)
How can I set up a proper alias_attribute to access the paperclip thumnail? I can't seem to find an answer anywhere else, and I am unsure how paperclip is actually working.
I thought I might logically be able to do something like
alias_attribute :image, :headerimage(:banner)
but that does not work.
You can just try this - basically call the original with arguments since aliases won't take parameter but we know the fixed parameter to pass:
alias :image, :headerimage
def headerimage(name=nil)
headerimage(name || :thumb)
end

skip carrierwave Integirty and Processing validation

I have white listed some of the extensions in the carrierwave uploader class
def extension_white_list
%w(doc docx)
end
In some cases I would like to skip the Integrity validation while saving a record. But as per their documentation validates_integrity_of validation exist by default.
https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Validate-uploads-with-Active-Record
can anyone please tell me how to skip such validation ?
in uploaders/file_uploader.rb
def extension_white_list
if model.do_i_need_validation?
%w(doc docx)
else
file.extension
end
end
and define this instance method in the model
def do_i_need_validation?
condition? ? true : false
end
Just replace the content of the method suitable to your app
I couldn't find anything about this in any of carrierwave's documentation, but reading its source code, one can pass specific uploader options in the mount_uploader call:
mount_uploader :field, MyUploader, options
Validations configuration do exist in uploader options, so you can, for example, disable all validations using:
mount_uploader :field, MyUploader, validate_download: false, validate_integrity: false, validate_processing: false
Note that when doing this the errors are silently ignored, so saves will succeed. This could be unexpected behavior. You can check if the operation actually had any errors using the model helpers <field>_processing_error, <field>_integrity_error and <field>_download_error:
class Article < ActiveRecord::Base
mount_uploader :image, ImageUploader, validate_integrity: false
end
article = Article.find(1)
article.update_attributes!(title: "New article title", image: open("/path/to/invalid_image.jpg")) # => this will actually succeed
article.image_integrity_error # => returns the error message from carrierwave

Paperclip image name changed after updating any attribute

This is my model
class Technology < ActiveRecord::Base
attr_accessible :name #etc ....
has_attached_file :logo, :path => ":rails_root/public/technologies/logos/:normalized_input_file_name"
Paperclip.interpolates :normalized_input_file_name do |attachment, style|
attachment.instance.normalized_input_file_name
end
def normalized_input_file_name
name = "#{self.name}".downcase
"#{self.tuid}_"+name.gsub(/[^a-zA-Z0-9]{2,}/,' ').strip.gsub(/\W/,'_').gsub(/\A_/,'').gsub(/_\z/,'')+"_150x"+".png"
end
end
When I create any technology, I upload a logo for it and the image stored in public directory with the new name as I want using the method "normalized_input_file_name".
e.g.technology name is HTML5 and file name becomes id_html5_150x.png
But when I need to update name the image path also changed.
e.g. HTML 5 file name becomes id_html_5_150x.png Here actual image file name is not updated
But path is updated. So I can't find the image.
Use a before_save hook to download and store the image again if you recognize that the name attribute going to change.
This code is totally untested but should give you an idea:
before_save do
if self.name_changed?
self.logo = logo.uploaded_file
end
end

Resources