Rails: download .to_pdf stuck on old revision of object - ruby-on-rails

I have a rails app and stuck on a problem when trying to create a download link to some dynamic generated data.
I've placed a .to_pdf method in my Folha model. And on controller folhas_controller.rb:
def show
nome = "#{#folha.nome_do_mes}-#{#folha.ano}-#{DateTime.now.to_i}"
#folha = Folha.find(params[:id])
respond_to do |format|
format.pdf do
pdf = #folha.to_pdf(view_context)
send_data pdf.render, filename: "#{nome}.pdf", type: "application/pdf"
end
end
end
The issue is that the .to_pdf method is executed only the first time i click the link. For all other clicks it gives me the same file, no matter if my object was updated.
I dont know where in my stack this is ocurring.
It only happens in production. Im using Rails 3.2.6 on Thin 1.4.1 deployed to heroku.
Please help =)

I used a workaround, pretty sure its not the proper way:
routes.rb
resources :folhas do
resources :servicos
end
match 'exportar/:id/:dummy' => 'folhas#show', as: "exportar"
and then on the view:
<%= link_to image_tag('pdf_small.png'), exportar_path(id: folha.id, dummy: DateTime.now.to_i, format: 'pdf'), class: 'item' %>
that way a different link is placed each time the view is rendered.

Related

Rails send_data using Rmagick image.to_blob not working

My application creates customized labels depending on an object's properties (make, model, etc.) and successfully saves them to the server. I'm trying to get it to send_data the image (using to_blob) directly to the browser so the user can immediately open and print the image, instead of saving it to the server first. I'm having a lot of trouble getting the sending to the browser part to work.
I'm using Rails (4.0.0) and rmagick (2.13.4). Please let me know if I can share any other information. Here's the code:
VIEW
<%= link_to fa_icon('qrcode', text: 'Print'),
labels_path(#warranty_item.qr_code, { format: :png }),
method: :post, remote: true, class: 'btn btn-xs btn-warning' %>
CONTROLLER
require 'rmagick'
def create
respond_to do |format|
format.png do
#img = Magick::Image.new(280, 100) { self.background_color = blue' }
#img.format = 'png'
#img_blob = #img.to_blob
send_data #img_blob, filename: 'test_label.png', disposition: 'inline', type: 'image/png'
end
end
end
In Rails' logs, this goes off without a hitch; no errors, no warnings, only a: Sent data test_label.png (0.7ms)
If I run #img.to_blob in the Rails console, it gives me this:
"\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x01 \x00\x00\x00$\x01\x03\x00\x00\x00\x13\xABua\x00\x00\x00\x04gAMA\x00\x00\xB1\x8F\v\xFCa\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xFA\x00\x00\x00\x80\xE8\x00\x00u0\x00\x00\xEA`\x00\x00:\x98\x00\x00\x17p\x9C\xBAQ<\x00\x00\x00\x06PLTE\x00\x00\xFF\xFF\xFF\xFF{\xDC\x99,\x00\x00\x00\x01bKGD\x00\x88\x05\x1DH\x00\x00\x00\x14IDAT8\xCBc`\x18\x05\xA3`\x14\x8C\x82Q#,\x00\x00\x054\x00\x01\xEA\xAF\x9B \x00\x00\x00\x00IEND\xAEB`\x82"
However, if I use the logger, Rails.logger.info #img.to_blob it gives me this:
�PNG
IHDR $�uagAMA��
�a cHRMz&�����u0�`:�p��Q<PLTE����{ܙ,bKGD�HIDAT8�c`�`��Q#,4ꯛ IEND�B`�
Like I'd mentioned above, if I simply save the image, #img.write('test_label.png'), it works perfectly. What am I doing wrong? What am I missing? The code executes, tested in the console it works, but it does not send the image data to the user's browser/downloads file so they can open it. Please help!
It cannot work. Your link with 'remote: true' is an ajax request. You can't download a image to disk from JS. It's a security concern.
read here: enter link description here

Deleting a public folder or file from a Rails3 view?

I have a user model where users can upload their profile image, using the Paperclip gem. This all works fine and stores the file in the /public/images/#{user.id}/medium or original or small directory.
However I need to create an method to be able to delete these files, could someone help me with this?
Here is the code I have so far:
app/views/users/index.html.erb:
<%= link_to "Delete", method: :file_cleanup, action: :destroy %>
app/controllers/users_controllers.rb:
def file_cleanup
File.delete(Rails.root + 'public/#{current_user.image.url}')
redirect_to :action => :edit
end
I have not added any routes as the page seems to load without any errors.
It should be as simple as:
def delete_image
#user.image.destroy
end
I'd use that as a hook like before_destroy :delete_image.
See: Rails Paperclip how to delete attachment?

How do I create a temp file and write to it then allow users to download it?

I'm working on my first application and I need some help with allowing my users to download a text file with certain variables that are being displayed on the page.
Take a shopping list for example.
Let's say you allow your users to create a shopping list of products, and then display the shopping list with the items on a shopping list page,
e.g. localhost:3000/list/my-list
Take a look at the example code below (which is probably incorrect):
File.open('shopping_list.txt', 'w') do |file|
file.puts 'Item 1: #{product_1.name}'
file.puts 'Item 2: #{product_2.name}'
file.puts 'Item 3: #{product_3.name}'
end
Which then creates a text file that has the following content:
Item 1: Eggs
Item 2: Butter
Item 3: Bread
Users should then be able to download this file (i don't want this file to be stored on the server) via a download link.
I have no idea how to achieve this, but I'm hoping you guys can guide me. :D
TL;DR
create text files populated with model data (perhaps create a method to achieve this?)
text files should not be stored on the server, but created as users click the download button (not sure if this is the rails way but perhaps someone could show me a better way)
I am assuming there is a resource for List with the attribute name as the name of the list and a list has_many Item which has an attribute description
First off, create a download path change your routes config/routes.rb
resources :lists do
member {get "download"}
end
Now if you run a rake routes in the console you should see a route like
/lists/:id/download
Whats more you should now have the helpers download_list_url & download_list_path to use in your view like
<ul>
<% #lists.each do |list| %>
<li> <%= list.name %> - <%= link_to 'Download List', download_list_path(list) %> </li>
<% end %>
</ul>
In your lists_controller add the action, and as you dont actually want to keep the file on the server disk just stream the data as a string
def download
list = List.find(params[:id])
send_data list.as_file,
:filename => "#{list.name}.txt",
:type => "text/plain"
end
Finally you see I have used a as_file method which you should add to the model (I prefer not to do this stuff in controllers, fat models, skinny controllers). So in the List model
def as_file
output = [self.name]
self.items.each {|item| output << item.description }
output.join("\n")
end
You say you don't want to store the file on the server, but "download" it on request; this sounds like you just want to generate and deliver a text document in response to the download link. There are several approaches, but you want to be sure of setting the mime-type so the browser sees it as a text file instead of an html document.
product_info = [
"Item 1: #{product_1.name}",
"Item 2: #{product_2.name}",
"Item 3: #{product_3.name}",
].join("\n")
render :text => product_info # implies :content_type => Mime::Type["text/plain"]
BTW, your example with open/puts above won't output what you think since single-quoted strings don't interpolate.
so, you wish to :
create text files populated with model data (perhaps create a method
to achieve this?)
text files should not be stored on the server, but
created as users click the download button (not sure if this is the
rails way but perhaps someone could show me a better way)
You have the right idea, here's what to do :
Create a method in your model to generate the text file contents. Let's say this method is called list_data
It seems like you have an existing controller action called my_list. Hence we can call our new method in the controller like so :
.
def my_list
# pre-existing code
respond_to do |format|
format.html # show html page as before
format.text do
send_data #list.list_data, :content_type => 'text/plain', :filename => 'my-shopping-list.txt'
end
end
end
To link to the download, just use link_to :action => my_list, :format => 'text'
See http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_data for full docs on send_data
Caveat & explanations : Using the method above, there isn't really an explicit creation of files, Rails is streaming it for you. Hence this method is not suitable for very large files, or when the generation of the file content will take a while. Use a delayed method to generate the file and store it - the file contents somewhere if that's the case - but we can use send_data once it has been generated
You could try a combination of TempFile and send_file. In your controller action ..
file = Tempfile.new('foo')
file.write("hello world")
file.close
send_file file.path
At Rails 2.3 you can use Template Streaming. Working with Redmine I can remember something like that, you have to adapt for your case. Reference: Streaming and file downloads
require "prawn"
class ClientsController < ApplicationController
# Generate a PDF document with information on the client and return it.
# The user will get the PDF as a file download.
def download_pdf
client = Client.find(params[:id])
send_data(generate_pdf, :filename => "#{client.name}.pdf", :type => "application/pdf")
end
private
def generate_pdf(client)
Prawn::Document.new do
text client.name, :align => :center
text "Address: #{client.address}"
text "Email: #{client.email}"
end.render
end
end
Using the Thong Kuah you must just change the "content_type" param:
def my_list
# pre-existing code
respond_to do |format|
format.html # show html page as before
format.text do
send_data #list.list_data, :content_type => 'text/plain', :filename => 'my-shopping-list.txt'
end
end
end

Rails jQuery with Ajax?

I'm a rails newbie and I cant seem to get jquery with ajax to work. I have installed the jquery-rails and done rails g jquery:install. Then I did a sample test by calling an alert in the application.js file and it worked. Then I created a controller action 'index' and made a link to it on one of my other pages. I thought to get ajax to work with it, I would simply create a index.js.erb file. However I then got an error saying template missing, so in my controllers' index action, I put the following code:
respond_to do |format|
format.html
format.js
end
However, I am not getting anything displayed on my page. In my index.js.erb file I have a simple alert message to test out if its working, and I cannot get that to even come up. Any suggestions? I don't know if it matters but I am using rails 3.0.7. Thanks in advance
RJS files didn't work with jQuery Plugin, so, you have to use *.js.erb extension in order to use javascript template, and these files are a kind of erb + javascript combination (like *html.erb files).
Just wrote this using rails 3.0.7, jquery plugin should be compatible with rjs syntax
routes.rb
get "main/index"
get "main/hello"
main_controller.br
class MainController < ApplicationController
def index
end
def hello
end
end
hello.js.rjs
page.alert("test");
index.html.erb
<%= link_to 'test', main_hello_path, :remote => true %>

How to create an atom feed in Rails 3?

I'm trying to set up a simple atom feed from my Posts model and I'm running into translation problems between rails 2 and rails 3.
I tried to accomplish this task with two steps:
Added the <%= auto_discovery_link_tag(:atom) %> to my /views/layouts/application.html.erb file.
Created a /views/posts/index.atom.builder file. The file contains:
atom_feed do |feed|
feed.title("Daily Deal")
feed.updated(#posts.first.created_at)
#posts.each do |post|
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
entry.author { |author| author.name("Justin Zollars")}
end
end
end
I see the RSS link in my browser, but the link opens with an error:
Too many redirects occurred trying to open
“feed:http://localhost:3000/posts”.
This might occur if you open a page
that is redirected to open another
page which then is redirected to open
the original page.
Where have I gone wrong?
Try specifying a path to the feed:
<%= auto_discovery_link_tag(:atom, posts_path(:atom)) %>
Maybe you need to specify the actual feed address?
auto_discovery_link_tag :atom, "http://mysite.com/posts.atom"
If you're using FeedBurner, you'll want to use that address instead.
Also, do you have some kind of before_filter blocking the access to that page?

Resources