I need a quick tip on something which seems really simple. I have some pictures inside private folder and would like to display them inside my View.
The only solution I found was this:
def show
send_file 'some/image/url', :disposition => 'inline', :type => 'image/jpg', :x_sendfile => true
end
I've read that :disposition => 'inline' should not trigger image download and allow me to display it inside my View. The problem is that each time I trigger show action, image download is automatically activated and it is automatically downloaded. View for show action is not displayed.
How can I display that image inside my View? Thank you.
The way I do it, and I'm not saying it's perfectly by the book, is I make a root for images and an action in the controller to render it.
So, for instance, in routes.rb
match '/images/:image', to: "your_controller#showpic", via: "get", as: :renderpic
In your controller:
def showpic
send_file "some/path/#{params[:image]}.jpg", :disposition => 'inline',
:type => 'image/jpg', :x_sendfile => true # .jpg will pass as format
end
def show
end
And in your view
<img src="<%= renderpic_path(your image) %>">
Here is a working example, with fewer parameters on "send_file"
def showpic
photopath = "images/users/#{params[:image]}.jpg"
send_file "#{photopath}", :disposition => 'inline'
end
I think the problem is type. From documentation:
:type - specifies an HTTP content type
So the proper HTTP content type should be image/jpeg instead of image/jpg, as you can see here. Try with:
:type => 'image/jpeg'
You also can list all available types coding Mime::EXTENSION_LOOKUP into a rails console.
Example:
Controller
class ImagesController < ApplicationController
def show_image
image_path = File.join(Rails.root, params[:path]) # or similar
send_file image_path, disposition: 'inline', type: 'image/jpeg', x_sendfile: true
end
end
Routes
get '/image/:path', to: 'images#show_image', as: :image
Views
image_tag image_path('path_to_image')
You would need to have the view use an image_tag to display on the view.
Similar question was raised here: Showing images with carrierwave in rails 3.1 in a private store folder
Related
Hello I try to download a jpeg image on rails by verifying that the Post exists and by recovering its id in parameter.
I try something but i got a error... I show you:
def download
send_file '/public/uploads/posts/#image/image.jpg', :type => 'image/jpeg', :disposition => 'attachment', :x_sendfile => true
end
private
def set_image
#image = Post.find(params[:id])
end
In my controller I have to in my routes get download.
And my link_to is:
<%= link_to "Download", download_posts_path %>
But rails say to me "Couldn't find Post without an ID".
I don't understand why... He dont't have the id but I dont't know why ?
Assuming you use set_image in a before_action filter.
First you should pass the post instance or id to your route helper :
If your route takes a param e.g. /posts/:id/download :
<%= link_to "Download", download_posts_path(#post) %>
<%= link_to "Download", download_posts_path(#post.id) %>
If not you can pass it with a query parameter e.g. posts/download/?id=1
<%= link_to "Download", download_posts_path(id: #post.id) %>
Both solution will provide you a params[:id] in your controller. Otherwise params[:id] will be nil and find raises an error.
Then there's something wrong in the download action as #DileepNandanam pointed out. You're not using your Post instance (#image) at all, you're just passing send_file a string containing "#image", not the variable but just a string. You may want to use interpolation to build a valid path to your image. For example if your #image has a :name which could be "image.jpg" you would do it like this:
send_file "/public/uploads/posts/#{#image.name}"
Or you could name your images with the post id like 13.jpg then you'll do :
send_file "/public/uploads/posts/#{#image.id}.jpg"
Or even create separate forlders with post's ids :
send_file "/public/uploads/posts/#{#image.id}/image.jpg"
send_file "/public/uploads/posts/#{#image.image_file_name}/image.jpg", :type => 'image/jpeg', :disposition => 'attachment', :x_sendfile => true
The method image_file_name may varies depends on the attachment you have specified on model
A better way is to use the url for attachment like
send_file #image.image.url(:original)
I am using rails 4.x with paperclip. I want to ensure that when the user clicks on a link to download a paperclip attachment, the file is downloaded instead of opening up.
The link I was using that would open or save depending on the browser configuration was
<%= link_to image_tag("save.gif", document.doc_file.url, :target => "_blank" %>
That link will sometimes open the file instead of downloading.
I set up a method of
helper_method :download
def download
#document= Document.find(39)
send_file ("http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf?1458068410"),
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
end
I hardwired the url for testing. I had also tried with send_file ("http://localhost:3000#{#document.doc_file.url}") and send_file (#document.doc_file.url). NEither worked.
My link to that is
<%= link_to image_tag("save.gif"), download_path(document.id) %>
routes.rb has
match 'documents/download/:id' => 'documents#download',via: [:get, :post], :as => 'download'
When I click on the download link, I get an error of
ActionController::MissingFile in DocumentsController#download
Cannot read file http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf
Rails.root: C:/Users/cmendla/RubymineProjects/technical_library
Application Trace | Framework Trace | Full Trace
app/controllers/documents_controller.rb:17:in `download'
If I put the URL into an address bar on a browser, it works. i.e. `http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf'
The send_file method accepts the physical location of the file on your server, not public URL. So something like the following should work, depending on where the PDF file actually resides:
send_file "#{Rails.root}/public/images/39/Medical_Opportunity_EvaluationForm.pdf",
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
If this is a paperclip document, the path method should work:
send_file #document.doc_file.path,
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
See the docs for more info.
I have an issue when I send an image with send_data method in Rails.
I have a controller with a helper method that sends the image data to an image tag
class HomeController < ApplicationController
helper_method :img
def index
end
def img
image.resize '1600x900'
image.rotate '180'
File.open(image.path, 'r') do |f|
send_data f, filename: 'gift_front.jpg', :type => 'image/jpeg', :disposition => 'inline'
end
end
end
And the view is just this line:
<%= image_tag img, alt: 'Loading Image...', title: 'image' %>
But when the page is loaded in the browser I get this error:
The image “http://localhost:3000/” cannot be displayed because it contains errors.
I use rails 4.1.2 and ruby 2.2.2. The rails log doesn’t show any errors. I need to get a functionality where image data is sent to the browser, from an image out of the project, and this looks like the only solution, but I can't find a solution to this error.
Can someone enlighten me how can I download file with send_file?
I have a file image.jpg inside app/assets/images. I've tried this in my controller:
def download
send_file ("#{Rails.root}/public/images/image.jpg")
end
def download
send_file ("#{Rails.root}/assets/images/image.jpg")
end
def download
send_file ("#{Rails.root}/images/image.jpg")
end
def download
send_file ("/public/images/image.jpg")
end
def download
send_file ("/assets/public/images/image.jpg")
end
def download
send_file ("/assets/images/image.jpg")
end
For each path it says:
ActionController::MissingFile in HomeController#download
Cannot read file 'some_path'
What could be a problem here? Thanks!
Try:
IMAGES_PATH = File.join(Rails.root, "public", "images")
def download
send_file(File.join(IMAGES_PATH, "image.jpg"))
end
In your view =>
<%= link_to "click here to download", signed_feeds_pdf_path(:feed_image_path => feed_image.feedimage.path), target: '_self' %>
In your controller =>
def pdf
file_name = params[:feed_image_path].split('/').last
#filename ="#{Rails.root}/public/uploads/feed_image/feedimage/#{file_name}"
send_file(#filename ,
:type => 'application/pdf/docx/html/htm/doc',
:disposition => 'attachment')
end
soo simple......
well, i suggest you to move your file to public folder. Anyway , do this
send_file(Rails.root.join('app' , 'assets', 'images', 'image.jpg'))
We need to specify the mine type so that it will cache.
send_file ("#{Rails.root}/public"+image.image_path), :type => "image/jpeg", :disposition => 'inline'
For anyone still looking for an answer, send_data and send_file won't work when responding to ajax calls. Instead, try submitting a form or using <a href=..> to call the controller method and download a file.
I'm trying to display images using my web application written in Rails. I've come across solutions like PaperClip, Attachment Fu etc; but they modify my data model and require to save the image through UI. The problem is that, the images content is not stored using Rails, but a Java Servlet Application. Is there a way to just display the blob content of image to my View.
-Snehal
class ImagesController < ApplicationController
caches_page :show
def show
if #image = Image.find_by_file_name(params[:file_name])
send_data(
#image.file_data,
:type => #image.content_type,
:filename => #image.file_name,
:disposition => 'inline'
)
else
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
end
end
end
map.connect "/images/*file_name", :controller => "images", :action => "show"
Or something like that.