Rails 3, Displaying Jpg Images from the Local File System Above Rails_Root

Rails 3, displaying jpg images from the local file system above RAILS_ROOT

For obvious reasons Rails won't allow a user to access parts of the filesystem outside of RAILS_ROOT/public. You were actually part of the way there when you mentioned sendfile (or x-sendfile for preference.) The solution is to have Rails serve up an html page as normal which contains links to a Rails action which serves up the individual files.

For example, let's say I want to show some images from somewhere deep in the filesystem. First I have to create an action that serves up one image at a time. So in the config/routes.rb you could add the following:

match '/serve_image/:filename' => 'images#serve'

Then I have to create a controller to match that route. For example:

class ImagesController < ApplicationController
def serve
path = "/my/servers/image/path/#{params[:filename]}"

send_file( path,
:disposition => 'inline',
:type => 'image/jpeg',
:x_sendfile => true )
end
end

Now your images are available under the url: /serve_image/my_image.jpg. So the last thing to do is create a nice html page that shows all the necessary images. It's as simple as:

<img src="/serve_image/image1.jpg">
<img src="/serve_image/image2.jpg">
<img src="/serve_image/image3.jpg">
<img src="/serve_image/image4.jpg">

Rails 3: How to get image path in Controller?

ActionController::Base.helpers.asset_path('missing_file.jpg')

Access Asset Path from Rails Controller

Unable to display remote images in rails

I'm assuming you must have loaded the remote urls into your products' table's productimage column.

Perhaps the simplest way to accomplish your goal would to be add something like a remote_url column to the products table and not put remote URLs in the productimage column. Then you could do something like:

Class Product < ActiveRecord::Base
def image_url
productimage.present? ? productimage_url : remote_url
end
end

Then change your view to:

<%= image_tag(product.image_url) if product.image_url.present? %>

If your products table is already populated with remote urls from your app previously using something other than carrierwave, another option that might be better would be to write a rake task to download and re-save them with carrierwave. That might look something like:

Product.all.each do |product|
temp_location = Rails.root.join('tmp', File.basename(product.attributes['productimage']))
uri = URI(product.attributes['productimage'])

Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new uri

http.request request do |response|
File.open(temp_location, 'w') do |file|
response.read_body do |chunk|
file.write chunk
end
end
end
end

product.productimage = File.open(temp_location)
product.save!

File.unlink(temp_location)
end

rails 5 carrierwave no route matches for image

The reason the image isn't being found is the web server's root is the Rails app's public directory, so it is looking for the image under "public/uploads/2/..."

Since the web server can't find the file it is passing the request to the Rails stack, and there is no route defined that matches, so it throws an error.

If you change your image upload root to be the public directory it should work as you expect.

UPDATE

If you don't want to put the images under the public directory you can create a route and controller action to serve the images. You can use the send_file method in the controller action. Take a look at this question:

Rails 3, displaying jpg images from the local file system above RAILS_ROOT


How Rails be configured to access a media resource that is not in its conventional directory location?

Rails does not serve these images, it lets the web server do that. You had best change the configuration of your web server to handle this scenario. If you use Apache, for example, it would fairly easy to set up with mod_rewrite.

Making Rails serve these images will be ugly, but it is possible if you provide a route in your routes.rb that matches /public/images/unconventional.gif, and if the file itself does not exist. For example:

map.connect "public/images/unconventional.gif",
:controller => "static_image_controller",
:action => "serve"

And then create a controller StaticImageController:

class StaticImageController < ApplicationController
def serve
image = File.read(File.join(Rails.root, "unconventional.gif"))
send_data image, :type => "image/gif", :disposition => "inline"
end
end

Warning: if you use the above concept, note that if you use input from the URL to decide which file to serve (with params[:file], for example), you need to thoroughly sanitize the input, because you are risking exposing your entire file system to the outside world.

img src= Isn't accepting image path

The image_tag helper prepends the path to the standard images folder into the path to the file. In my version of rails this is "/images/", so this

<%=image_tag("Flower.jpg")%>

is rendered out as

<img src="/images/Flower.jpg">

As with all resource paths like this, the actual file should be relative to your apps' public folder, ie

<RAILS ROOT>/public/images/Flower.jpg

In your version of rails it looks like the default path is /app/assets/images/, so this

<%=image_tag("Flower.jpg")%>

is rendered out as

<img src="/app/assets/images/Flower.jpg">

which points to this file:

<RAILS ROOT>/public/app/assets/images/Flower.jpg

If you do

<img src="Flower.jpg">

it will expect the file to be in <RAILS ROOT>/public/Flower.jpg, and obviously it's not there, so the img tag won't work. If you want to write it out yourself, without using a helper, then give the path to the file from the <RAILS ROOT/public folder, ie

<img src="/app/assets/images/Flower.jpg">

BTW in your snippet of html you put scr=" instead of src=" which is going to break it even more.

how to reference to an image in seeds.rb

Suppose you are saving your images under public/images, Carrierwave requires that you pass an IO object to the Rails model, so to set it up correctly in the seeds.rb file you instead need to do:

User.create!(
name: "Example User",
email: "example@railstutorial.org",
password: "foobar",
password_confirmation: "foobar",
admin: true,
politics: 'left',
car: true,
pets: 'I like horses and bears',
music: 'American country and folk',
picture: File.open(Rails.root.join('public', 'images', 'pic1.jpg')),
profile: 'I like music and the Ruby and Python programming languages',
activated: true,
activated_at: Time.zone.now
)

See that I've changed picture to File.open(Rails.root.join('public', 'images', 'pic1.jpg'))



Related Topics



Leave a reply



Submit