Carrierwave object.url VS object.image_url - ruby-on-rails

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

Related

Carrierwave remote attachment url not working on creation

I have the following model called ApplicationAttachment in my Ruby on Rails project.
I also have uploaded files on my s3 bucket. When i try to upload the image to my model, i dont get an error but attachment is nil and the remote_attachment_url is not saving the file. Not sure what is the problem.
My code is this
ApplicationAttachment.create!(remote_attachment_url: "http://www.jqueryscript.net/images/jQuery-Plugin-For-Fullscreen-Image-Viewer-Chroma-Gallery.jpg")
This doesnt return any error but it doesnt save the image.
class ApplicationAttachment < ActiveRecord::Base
mount_uploader :attachment, DeveloperReferralAttachmentUploader
attr_accessible :id, :attachment, :remote_attachment_url, :created_at, :updated_at
end
class DeveloperReferralAttachmentUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(pdf jpg jpeg gif png)
end
end
How do i ensure that the remote_image_url saves when created via Carrierwave.
Thanks
I think you might want to explicitly save the attachment instead of using create.
aa = ApplicationAttachment.new(
remote_attachment_url: "http://www.jqueryscript.net/images/jQuery-Plugin-For-Fullscreen-Image-Viewer-Chroma-Gallery.jpg"
)
aa.save

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

Carrierwave: How to validate that image is attached? (either upload, or remote_url)

I'm trying to make sure that every instance of Picture model has a file attached.
In other words - there are two fields in the form:
:file
:remote_file_url
I want user to fill in at least one of them.
When I validate presence of :file, and submit remote_file_url instead of file - then it gives validation error.
The only way I found for now is do smth like this:
class Picture < ActiveRecord::Base
validate :file_xor_remote_file_url
private
def file_xor_remote_file_url
if !(file.blank? ^ remote_file_url.blank?)
errors.add(:base, "Specify a file to upload, or file URL, not both")
end
end
end
The wiki says you can validate your upload like this:
mount_uploader :avatar, AvatarUploader
validates_presence_of :avatar
It doesn't mention any different handling for remote URLs, but underlines that Carrierwave validates the presence of the file rather than just the presence of an URL. So a given remote URL must refer to a valid file that can be uploaded.
You said that "validate presence of :file", but perhaps this could be the point. Hope this helps.

Rails carrierwave mounting on condition

I need to mount picture uploader after some verification function.
But if I call as usual mounting uploader in model:
mount_uploader :content, ContentUploader
carrierwave first download content, and then Rails start verification of model.
Specifically, I don't want to load big files at all! I want to check http header Content-length and Content-type and then, if it's OK, mount uploader.
Maybe something like that:
if condition
mount_uploader :content, ContentUploader
end
How can I do it?
P.S. Rails version 3.2.12
This is not the way to go if you just want avoid loading big files! That said, one can have conditional mount overriding content=.
As CarrierWave v1.1.0 there is still no conditional mount. But note that mount_uploader first includes a module in the class and then overrides the original content= to call the method content= defined in the included module. So, a workaround is just to redefine the accessors after you have called mount_uploader:
class YourModel < ActiveRecord::Base
mount_uploader :content, ContentUploader
def content=(arg)
if condition
super
else
# original behavior
write_attribute(:content, arg)
end
end
def content
# some logic here
end
end

Resources