0
votes

I have uploaded images with carrierwave under the public folder. For security reason, I'm going to change the folder to under the root.

Althogh I referred to the post How to: Secure Upload and created carrierwave.rb, I don't know how to write the path uploaded by carrierwave.

How can I display images under private folder?

image_uploader.rb

class ImageUploaader < CarrierWave::Uploader::Base

  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

end

I created \config\initializers\carrierwave.rb

CarrierWave.configure do |config|
  config.permissions = 0600
  config.directory_permissions = 0700
  config.root = Rails.root
end

I also created images_controller.rb

class ImagesController < ApplicationController
    #I tried some, but doesn't work
end

I have used the following view to display images.
\views\articles\ _article.html.erb

<% article.photos.each do |photo| %>
  <%= image_tag(photo.image_url(:thumb).to_s, class: :thumb) if photo.image? %>
<% end %>

It would be appreciated if you could specify the code in routes.rb, images_controller.rb and _article.html.erb.

2

2 Answers

0
votes

I'm running through Rails 4 In Action and we had a similar need. In that book they had us create a folder under the app root called "files".

Then we changed the line in your uploader from:

uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}

to

files/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}

Now, in that book, files get dropped to the files directory. You then set permissions using something like CanCanCan or writing it yourself. That seems to be it. I think.

0
votes

It's an old question, maybe it will help someone as it helped me. I think you misunderstand the explanation in the reference: Add this route:

match "/uploads/photos/:id/:basename.:extension", controller: "photo", action: "send_img", via: :get

So every URL requests like: /uploads/photos/1/best_ever_img.png will be "redirected" to send_img action in photos controller

On your action,

class Photos mount_uploader :image, ImageUploaader

def send_img
    id = params[:id]
    basename = params[:basename]
    extension = params[:extension]
    type = params[:type]
    # if you have a different environment in your dev and production, you can add each unique route
    if Rails.env.development?
        # The route to your project folder
        # My dev server is on windows Linux shell so the route is like this, you may use other development environment so just update the route
        base_url = "/mnt/c/Users/YOUR_USER_NAME/Desktop/Sites/"
    else
        base_url = "/home/deploy"
    end
    # Replace the `YOUR_PROJECT_FOLDER` with name of yours
    path = "#{base_url}/YOUR_PROJECT_FOLDER/uploads/photos/image/#{id}/#{basename}.#{extension}"
    send_file path, x_sendfile: true
end

In your view, load the image like this:

<%= image_tag "uploads/photos/#{photo.id}/#{File.basename(photo.image.url)}" %>