Rails activeadmin Export PDF - ruby-on-rails

I'm helping a friend with a ruby on rails site. I'm really new at ruby on rails and the developer that developed the site is long.
The app uses the activeadmin gem and currently there is a column in the documents section that supposedly exports the document in PDF format but is not working. Here is the code. From app/admin/documents.rb
ActiveAdmin.register Document do
index do
column :id
# This was buggy
column :user_name do |d|
d.user.nil? ? 'No User' : (link_to d.user.name, admin_user_path(d.user))
end
column :user_email do |d|
d.user.nil? ? 'No User' : d.user.email
end
column :price do |document|
document.price.nil? ? 'Gratis' : document.price
end
column :type_document
column :status
column :download do |document|
link_to 'Download PDF', document_path(document, format: :pdf)
end
default_actions
end
form do |f|
f.inputs "Edicion" do
f.semantic_errors
f.input :content
f.input :price
f.input :status, as: :select, collection: Document::STATUSES
f.actions
end
end
csv do
column :user_name
column :user_email
column :price
column('Tipo') { |document| document.type_document }
column :status
column(:content) { |document| strip_tags(document.content) }
end
end
I Installed the wicked_pdf gem, but I'm stuck here. I do not know how to proceed. I found this code to generate the PDF
def generate_pdf(document)
pdf = WickedPdf.new.pdf_from_string(
document.content,
encoding: 'UTF-8',
page_size: 'A4',
orientation: 'Portrait',
template: 'documents/documento.pdf.rb',
margin: { top: 30, # default 10 (mm)
bottom: 30,
left: 20,
right: 20
},
layout: 'layouts/pdf.html'
)
send_data(
pdf,
filename: "document_#{document.type_document}_#{document.user.name}.pdf",
disposition: 'attachment'
)
end
I'm not sure if that code is correct and also how can I link the Download PDF link to this function?
Any help would be greatly appreciated.
Thanks in advance
Carlos Sosa

You already have the download PDF link here:
link_to 'Download PDF', document_path(document, format: :pdf)
The generate_pdf method contents could be added to, or called from, that controller endpoint.
Assuming you already have a DocumentsController#show action, it could look something like this:
def show
#document = Document.find(params[:id])
respond_to do |format|
format.html # render existing view
format.pdf do
generate_pdf(#document)
end
end
end
private
def generate_pdf(document)
# same content you posted
end

Related

How to upload correctly CSV file in Rails

I am trying to upload a csv file with Rails from Active Admin.
I have a model User, which has columns name(string) and age(integer).
My csv file looks like this:
name,age
"Peter",31
"Susan",30
"John",40
Then I have in my admin/user.rb:
ActiveAdmin.register User do
permit_params :name, :age
collection_action :upload_csv do
render "admin/csv/upload_csv_user"
end
collection_action :import_csv_data_user, :method => :post do
ret_val = CsvDb.update_model_from_csv("user", params[:dump][:file])
redirect_to :action => :index, :notice => ret_val
end
end
And in my admin/csv/upload_csv_user.html.erb I have:
<%= form_for(:dump, :url=>{:action=>"import_csv_data_user"}, :html => { :multipart => true }) do |f| %>
<%= f.file_field :file %>
<%= f.submit "Submit", confirm: "Are You Sure?" %>
<% end %>
Inside a csv_db.rb file I have:
require 'csv'
module CsvDb
def self.update_model_from_csv(model_name, file)
csv_data = CSV.read(file.path)
columns = csv_data.shift
model = model_name.classify.constantize
ret_val = "Data updated successfully!"
begin
model.import columns, csv_data, on_duplicate_key_update: columns, validate: false
rescue Exception => e
ret_val = e
end
ret_val
end
end
When I try to upload the file I get the following error: Illegal quoting in line 1.
And below it's written:
part "\"name"
parse "\"name,age\""
parts ["\"name", "age\""]
unconverted nil
in_extended_col false
csv []
I checked lots of examples and I can't find the error. Maybe my csv file is formatted incorrectly.
require 'csv'
module CsvDb
def self.update_model_from_csv(model_name, file_params)
CSV.foreach(file_params.path, headers: true) do |row|
model = model_name.classify.constantize
begin
name = row["name"]
age = row["age"]
if model.create(name: name, age: age)
result = "Imported successfully!"
end
rescue Exception => e
result = e
end
end
result
end
end
Use this method in controller as: -
#pass model name and params[:file], which is csv uploaded from user end
CsvDb.update_model_from_csv(model_name, params[:file])

Rails Elastics Search Result content URL error

I was just trying out the Elastic Search in my Rails app replacing the existing search function. Everything worked nicely but I am getting http://localhost:3000/contents/video/%23%3CElasticsearch::Model::Response::Result:0x007fe24e118f40%3E url.
in content.rb
def to_param
"#{id}/#{title.parameterize}.html"
#"#{id}-#{title.downcase.slice(0..30).gsub(/[^a-z0-9]+/i, '-')}.html"
end
and in search action
def search
if params[:q].nil?
#indexs = []
else
#indexs = Content.search params[:q]
end
and in views
<% #indexs.each do |f|%>
<%= link_to((truncate f.title, length: 60), {:controller => "contents", :action => "weblinks", :id => f.to_param}, target: "_blank") %>
<% end %>
It works fine for the default listing page, but its URL generating error in search result page. Please help,and also how to replace the {:controller => "contents", :action => "weblinks", :id => f.to_param} with weblinks_path(:format) routes
I assume you use elasticsearch gem, if so you should use records to get ActiveRecord models #indexs.records

How to export a HTML file in Rails?

I am trying to export links that are in my database into a HTML Netscape Bookmark File using Markio.
This following Ruby code is from Markio. I'm not sure how to get it to work with Rails so I can export links from my database to a file the user can download.
builder = Markio::Builder.new
builder.bookmarks << Markio::Bookmark.create({
:title => "Google",
:href => "http://google.com"
})
file_contents = builder.build_string
File.open('/path/to/bookmarks.html', 'w') { |f| f.write file_contents }
This is what I have so far in my Rails app. I am most likely going about it completely wrong because I only know how to do it with CSV and Excel. Each Link in my Rails database has a title and a url.
If I navigate to links/export in my browser it should download a file but I get the error "uninitialized constant Markio::Link".
This is my Links controller:
def export
#links = Link.all
respond_to do |format|
format.html { send_data #links.to_csv }
end
end
This is my Links model:
def self.to_csv(options = {})
builder = Markio::Builder.new
builder.bookmarks << Markio::Link.create({
:title => title,
:href => url
})
file_contents = builder.build_string
File.open('/path/to/bookmarks.html', 'w') { |f| f.write
file_contents }
end
Shouldn't Markio::Link be Markio::Bookmark? I don't see a Link object in their API.

Rails 4 - saving images in database

Hello dear Programmers,
I'm trying to develop a web application with the ebook "Praxiswissen - Ruby on Rails". My problem is that I want to save Images through a form to my project directory. The database just saves the name of the pictures with the saving time:
def unique_and_proper_filename(filename)
Time.now.to_i.to_s + '_' + File.basename(filename)
end
My problem is that my pictures dont get saved after submitting my form. I dont get some exceptions, thats why I dont know where my issue is.
Controller:
class PostsController < ApplicationController
require 'will_paginate'
def new
#post = Post.new
end
# information about saving the picture
def create
#post = Post.new(params[:post].permit(:title, :description, :date, :image_file, :thumbnail_file))
# Form isn't correctly filled message
if !#post.valid?
flash.now[:notice] = "Bitte füllen Sie alle Felder aus und überprüfen Sie Ihre Angaben."
render(:action => :new)
# Files weren't saved message
elsif !#post.save_files
flash.now[:notice] = "Es trat ein Fehler beim Hochladen der Dateien auf."
render(:action => :new)
# Files saved correctly message
else
#post.save
flash[:notice] = "Dateien wurden hochgeladen und die Daten wurden gespeichert."
redirect_to(:action => :list)
end
end
# list action for listing my pictures
def list
#posts = Post.paginate(:page => params[:page], :order => "date DESC", :per_page => 15)
#post_pages = Post.paginate(:page => params[:page], :order => "date DESC", :per_page => 15)
end
end
HTML Form:
<h2>Neues Foto anlegen</h2>
<%= form_tag({:action => :create}, :multipart => true) %>
<h3>Bilddaten</h3>
<p>
Titel<br/>
<%= text_field(:post, :title) %>
</p>
<p>
Beschreibungen<br/>
<%= text_field(:post, :description) %>
</p>
<p>
Datum und Uhrzeit<br/>
<%= datetime_select(:post, :date, :order => [:day, :month, :year, :hour]) %>
</p>
<p>
<h3>Datei-Upload</h3>
<p>
Bilddatei:<br/>
<%= file_field(:post, :image_file) %>
</p>
<p>
Thumbnail:<br/>
<%= file_field(:post, :thumbnail_file) %>
</p>
<%= submit_tag("Speichern") %>
</p>
</form>
Model:
class Post < ActiveRecord::Base
validates_presence_of(:title, :description, :date, :image, :thumbnail)
I18n.enforce_available_locales = false
def image_file= (fileobj)
if fileobj.size > 0
#image_file = fileobj
self.image = unique_and_proper_filename(fileobj.original_filename)
end
end
def thumbnail_file= (fileobj)
if fileobj.size > 0
#thumbnail_file = fileobj
self.thumbnail = unique_and_proper_filename(fileobj.original_filename)
end
end
def save_files
# Bilddatei save
if !save_uploaded_file(#image_file, IMAGE_DIR, self.image)
return false
end
# Thumbnail save
if !save_uploaded_file(#thumbnail_file, THUMBNAIL_DIR, self.thumbnail)
return false
end
end
private
def unique_and_proper_filename(filename)
Time.now.to_i.to_s + "_" + File.basename(filename)
end
private
def save_uploaded_file(fileobj, filepath, filename)
# Complete Path
complete_path = Rails.root + "/public/" + filepath
# if neccessary, create directory
FileUtils.mkdir_p(complete_path) unless File.exists?(complete_path)
# save data
begin
f = File.open(complete_path + "/" + filename, "wb")
f.write(fileobj.read)
rescue
return false
ensure
f.close unless f.nil?
end
end
end
I'm only getting the message that there went something wrong with saving the files when i fill the form correctly but it should return a message that says that my file were saved.
I'm sorry for that massive length of my question but I really dont know where my issue is... If there's a need for more information or code, I will add it as fast as I can.
Thank you very much in advance!
Update 17/02/22:
Paperclip has since been deprecated, it is recommended you use Rails' own Active Storage.
Original Answer:
I'm sorry but I'll only be able to recommend what we use:
Paperclip
I appreciate you're using a tutorial, but I'd highly recommend using the Paperclip gem for this
This handles ALL the heavy lifting for you:
#GemFile
gem "paperclip", "~> 4.1.1"
Model
#app/models/post.rb
Class Post < ActiveRecord::Base
has_attached_file :image
end
#migration
add_attachment :posts, :image
Controller
#app/controllers/posts_controller.rb
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
end
private
def post_params
params.require(:post).permit(:image, :other, :params)
end
View
#app/views/posts/new.html.erb
<%= form_for #post do |f| %>
<%= f.file_field :image %>
<% end %>
I'm lucky to tell that I found my issue. My save_files method in my Post model doesn't returned true..
I post this answer because maybe someone could use this question as an answer for his own problem. Here's where I added my return true :
def save_files
# Bilddatei save
if !save_uploaded_file(#image_file, IMAGE_DIR, self.image)
return false
end
# Thumbnail save
if !save_uploaded_file(#thumbnail_file, THUMBNAIL_DIR, self.thumbnail)
return false
end
return true # <--------- Need to be added!
end
Try to add enctype= multipart/formdata in your form tag if you are using form to post your data

uninitialized constant CustomersController::CSV

I'm following the tutorial http://www.funonrails.com/2012/01/csv-file-importexport-in-rails-3.html]for upload files in rails 3, because I need that my app's user could upload csv files but when I tried to save the file I get: uninitialized constant CustomersController::CSV message, before change my routes to get "customers/import" to post "customers/import" I had other error No route matches [POST] "/customers/import" what Im doing wrong? thanks in advance.
MY CONTROLLER:
class CustomersController < ApplicationController
def import
if request.post? && params[:file].present?
infile = params[:file].read
n, errs = 0, []
CSV.parse(infile) do |row|
n += 1
# SKIP: header i.e. first row OR blank row
next if n == 1 or row.join.blank?
# build_from_csv method will map customer attributes &
# build new customer record
customer = Customer.build_from_csv(row)
# Save upon valid
# otherwise collect error records to export
if customer.valid?
customer.save
else
errs << row
end
end
# Export Error file for later upload upon correction
if errs.any?
errFile ="errors_#{Date.today.strftime('%d%b%y')}.csv"
errs.insert(0, Customer.csv_header)
errCSV = CSV.generate do |csv|
errs.each {|row| csv << row}
end
send_data errCSV,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=#{errFile}.csv"
else
flash[:notice] = I18n.t('customer.import.success')
redirect_to import_url #GET
end
end
end
end
MY MODEL:
class Customer < ActiveRecord::Base
scope :active, where(:active => true)
scope :latest, order('created_at desc')
def self.csv_header
"First Name,Last Name,Email,Phone,Mobile, Address, FAX, City".split(',')
end
def self.build_from_csv(row)
# find existing customer from email or create new
cust = find_or_initialize_by_email(row[2])
cust.attributes ={:first_name => row[0],
:last_name => row[1],
:email => row[3],
:phone => row[4],
:mobile => row[5],
:address => row[6],
:fax => row[7],
:city => row[8]}
return cust
end
def to_csv
[first_name, last_name, email, phone, mobile, address, fax, city]
end
end
*MY VIEW:
<h1>Subir Archivos</h1>
<%= form_tag('import', :multipart => true) do %>
<p>
File:<br />
<%= file_field_tag 'file' %><br />
</p>
<p>
<%= submit_tag "subir" %>
</p>
<% end %>
MY ROUTES:
Pruebaupcsv::Application.routes.draw do
post "customers/import"
You need to add a require 'csv' before you use it, either in an initializer, or at the top of your controller.

Resources