CamelCamelCamel
CamelCamelCamel

Reputation: 5200

Carrierwave - "uploading" a file from a string

Users in my site can upload their own photos for a model or choose from a library. When the users choose from the library I send the file name as a string to the server {file: {url: 'url.jpg'}}. I haven't find a way in which carrierwave can just update a model file without uploading it. I can write a condition in my model that checks for the existence of that parameter and then model.file = File.open('str.jpg'). Is that bad from a security view? How can I "upload" files, or just update the file attribute, to reference a file that's already available on the server?

Thanks!

Upvotes: 9

Views: 3433

Answers (2)

Zachary Anker
Zachary Anker

Reputation: 4520

Your solution of using File.open would work, but you should verify that the name is valid with File.basename so someone couldn't pass ../../secret_credentials.yml and expose info you don't want them to. Also checking it against the list of preset images would be a good idea.

However, you can do this more efficiently by skipping CarrierWave in this case.

Add a new field called library_image, when someone wants to use a preset image, then you set library_image, if they want to use their own photo, unset library_image and upload the photo as normal. Then add a helper method like:

def avatar_url
    if self.library_image?
        "http://example.com/images/#{self.library_image}"
    else
        self.picture.url
    end
end

This assumes that you can find the preset images at http://example.com/images/[name] and you are using mount_uploader in CarrierWave named picture.

Now anytime you want to display their picture, you would call avatar_url which will check if it should return the preset URL, or the picture they uploaded.

An example of how you would update library_image or picture based on your original question:

if params[:file].is_a?(Hash)
    model.library_image = params[:file][:url]
    model.remove_picture = true
else
    model.library_image = nil
    model.picture = params[:file]
end

Upvotes: 4

dennis
dennis

Reputation: 2020

I would make another resource called LibraryImages wich holds these image files.

These would be in a relation with the User class using the has_many association. the second is to seperate when a user wants to use its own image instead of a pre defined one.

therefor I would suggest adding a boolean type called 'use_library', once they choose to use their own image it will just upload to the user.image without any problems.

now in your view just ask if the use_library returns true if so use image_tag(user.library_image)

Upvotes: 3

Related Questions