I have been trying to create a table in a pdf i am generating using Prawn gem in rails. I have been following some tutorial but when I try adding the table to the pdf I am getting the error '#<NoMethodError: undefined method `table' for #PdfMethods:0x0000023fc7b70648>'.
Here is my code:
require "prawn"
class PdfMethods < Prawn::Document
def initialize
super
pdf_text
statement_accounts
end
def pdf_text
text "Order goes here", size: 40, style: :bold
end
def statement_accounts
move_down 20
table_data = Array.new
table_data << [[1, 2], [3, 4]]
table(table_data)
end
end
I have already installed both the prawn and prawn-table gems. Any help will be appreciated.
For many years (like since 1.2, so 7, 8 years?), table support has been in another gem called prawn-table, you'll need to have that in your project too, then Prawn::Document supports the table method. Maybe get a newer tutorial? ;)
Related
I'm saving the result of this method to file in json format:
class VideosController < ApplicationController
...
def getting_hash
video = Video.new
video.id = 12
video.title = "How to make it work?"
video.desc = "No idea..."
video_hash = Hash.new
video_hash[video.id] = {id: video.id, title: video.title, desc: video.desc}
write_to_file(video_hash)
end
...
end
So for saving to the file I use:
def write_to_file(model)
path = "#{Rails.root}/public/my_file.cache"
open(path, 'w') { |f|
f.write(model.to_json)
}
end
Seems like vanilla, but when I use:
read_from_file(my_file.cache)
def read_from_file(file_name)
path = Rails.root + "public/#{file_name}"
file = File.read(path)
hash_to_return = JSON.parse(file)
end
It returns not the hash, but an array!
NoMethodError (undefined method `id' for #<Array:0x007f1926325460>):
And when I check:
["12", {"id"=>"12", "title"=>"How to make it work?", "description"=>"No idea..."}]
I don't understand how is that possible, because if I use variables it makes everything perfect like:
(byebug) test = {"12":{"id":12,"title":"How to make it work?","desc":"No idea..."}}
{:"12"=>{:id=>12, :title=>"How to make it work?", :desc=>"No idea..."}}
(byebug) test2 = test.to_json
"{\"12\":{\"id\":12,\"title\":\"How to make it work?\",\"desc\":\"No idea...\"}}"
(byebug) JSON.parse(test2)
{"12"=>{"id"=>12, "title"=>"How to make it work?", "desc"=>"No idea..."}}
Please, help me with getting correct hashes back! Any ideas are highly appreciated!
UPDATE
JSON::ParserError (lexical error: invalid char in json text.
{"12"=>{:id=>"12", :title=>
(right here) ------^
):
UPDATE 2
my_file.cache's output:
{"12":{"id":"12","title":"How to make it work?","description":"No idea..."},"14":{"id":"14","title":"Yoga","description":"Guide"}}
UPDATE 3
For now I've overriden this situation with: video_hash = Hash[*hash_to_return.flatten] and got the desired format.
So back home I'll try with running plain ruby file (as rwold said) and also I'll test the approach by ahmed eshra.
Sincere thanks to all who participated!
UPDATE 4
I tried my code as a plain ruby file outside Rails (with slight modifications) and it worked perfectly!
I think passing the object itself with to_json conversion, is better for what you need and it will be saved as hash.
def getting_hash
video = Video.new
video.id = 12
video.title = "How to make it work?"
video.desc = "No idea..."
# Removing the hash conversion step
write_to_file(video)
end
I'm using activerecord-import gem to import multiple ActiveRecord documents in single query. Then I'm initializing related associations using saved documents ids and importing them too, and so on.
However, I need to have PaperTrail gem versions with create event for all saved documents.
Is there some straightforward way to initialize them to make possible perform bulk insert then?
NOTE: AR-Import gem ignores all callbacks, so I have manually handle them after importing.
Thanks!
UPD-20/05/17:
At the moment I've solved this with the patch for PaperTrail::Model. Here is my .../initializers/paper_trail.rb:
module PaperTrail
class Version < ActiveRecord::Base
...
end
module ModelPatch
extend ActiveSupport::Concern
included do
# new method added to PaperTrail::Model module to make possible initialize
# `create` versions right after importing resources.
# This method contains modified code from private PaperTrail::Model::InstanceMethods#record_create
# Difference:
# - instead of `create!` we use `new` but with validation and raise exception if it's invalid.
# This is for reinsurance that if something changes after update PaperTrail gem in future
# everything still works or need to fix it.
def initialize_record_create_version
return nil unless paper_trail_switched_on?
data = {
event: paper_trail_event || 'create',
whodunnit: PaperTrail.whodunnit
}
if changed_notably? && self.class.paper_trail_version_class.column_names.include?('object_changes')
data[:object_changes] = if self.class.paper_trail_version_class.object_changes_col_is_json?
changes_for_paper_trail
else
PaperTrail.serializer.dump(changes_for_paper_trail)
end
end
new_v = send(self.class.versions_association_name).new merge_metadata(data)
new_v.valid? ? new_v : fail("Invalid PaperTrail Version: #{new_v.errors&.messages}")
end
end
end
end
PaperTrail::Model.send(:include, PaperTrail::ModelPatch)
UPD-28/01/21:
with PaperTrail v10.x.x works this:
def initialize_record_create_version
return nil unless paper_trail.enabled?
event = Events::Create.new(self, false)
data = event.data.merge!(paper_trail.data_for_create)
new_v = send(self.class.versions_association_name).new data
new_v.valid? ? new_v : fail("Invalid PaperTrail Version: #{new_v.errors&.messages}")
end
Yes, it should be possible to bulk-insert records into your versions table.
insert into versions
(item_id, item_type, event, created_at)
(1, "User", "create", "2016-02-29"),
(2, "User", "create", "2016-02-29"),
(1, "Widget", "create", "2016-02-29")
Because it is possible with plain SQL, it is also possible with ActiveRecord. Remember, PaperTrail::Version is a regular AR model.
I am using the prawn gem with Rails 4
I have the following gems:
gem 'prawn'
gem 'prawn-table'
gem 'prawn-qrcode'
I get the following error:
Prawn::Errors::UnrecognizedTableContent
When I do this:
require 'prawn/qrcode'
class ReportPdf < Prawn::Document
def initialize(organizations)
super()
#organizations = organizations
table_content
end
def table_content
table organization_rows do
row(0).font_style = :bold
self.header = true
self.row_colors = ['DDDDDD', 'FFFFFF']
self.column_widths = [40, 300, 200]
end
end
def organization_rows
[['#', 'Name', 'id']] +
#organizations.map do |organization|
[render_qr_code(RQRCode::QRCode.new(organization.id.to_s)), organization.name, organization.id]
end
end
end
Can anyone help by providing an example of adding a QR code to each row in a table?
UPDATE:
I changed my table code to the following (I added .to_s to the qr code:
def organization_rows
[['#', 'Name', 'id']] +
#organizations.map do |organization|
[render_qr_code(RQRCode::QRCode.new(organization.id.to_s)).to_s,
organization.name,
organization.id]
end
end
Now, I get the following pdf. See screenshot. How can I get those QR codes inside of a table cell?
You currently use:
def organization_rows
[['#', 'Name', 'id']] +
#organizations.map do |organization|
[render_qr_code(RQRCode::QRCode.new(organization.id.to_s)).to_s,
organization.name,
organization.id]
end
end
This results in prawn-table to convert and render the QRCode as string.
By default tables accept he following data as table cells:
String: produces a text cell (the most common usage)
Prawn::Table::Cell
Prawn::Table
Array
Images
Unfortunately I don't have the time right now to really dig into this problem, but judging from the documentation at: http://prawnpdf.org/docs/0.11.1/Prawn/Table/Cell.html,
you most likely need to create a subclass of Prawn::Table::Cell, that renders the QR code by implementing the #draw_content() method.
You also might have to adjust/constrain the table cell dimensions to provide miminum size to fit the QRCode by implementing #set_width_constraints()
I'm trying to generate a pdf document with different QRcodes and am using the following gems
gem 'prawn'
gem 'prawn-qrcode'
Issue is, I can't seem to print out the QRcode with the following method:
require 'prawn/qrcode'
class QrcodePdf < Prawn::Document
def initialize (deal)
super()
#deal = deal
title
#deal.venues.each do |venue|
text "QR Code for: #{venue.name}"
qrcode = RQRCode::QRCode.new(#deal.id.to_s + "_" + venue.id.to_s + "_" + #deal.created_at.to_s)
render_qr_code(qrcode)
end
end
def title
text "Title of deal: #{#deal.title}", size: 16, style: :bold
end
end
Any help will be appreciated! Thank you!
Edit: Additional Info
Sorry, i forgot to state that the pdf is actually being compiled. But the QRCode section is blank.
So it just print the text of QR Code for ... in the loop.
Also, I've printed out the string in #deal.id.to_s ... and it does contain the data I want, so I'm not sure what went wrong.
I've also refereed to https://github.com/jabbrwcky/prawn-qrcode in the usage section.
It's probably bug with prawn-qrcode, but render_qr_code is not working. At least for Ruby 2.2.3 (I didn't tested if for older versions).
Still you can use print_qr_code method and it's functional:
pdf = Prawn::Document.new(:page_size => "A4") do
print_qr_code("some-text", extent: 96, stroke: false)
end
I'm trying to create a pdf report using prawn in a rails application. There are lots of sections that contain user generated content that I want to try and group together. Sometimes this will go over more that one page which results in a cannot group error. I then tried to use a transaction so that in the event of an error I can rollback and then output the content without using the group method.
The problem is the rollback stuffs up the pages. It removes the extra page from the pdf but still has the wrong page count and outputs over lapping content when I try to redo it. I reset the y position after the rollback, as per the prawn documentation but I still get the problems.
eg. The following test code writes 2 pages of numbers, does a rollback to the start and then tries to write the same numbers again. It results in a single page pdf with the second page of numbers overlapping the first and a page count of 2. The page counts at the bottom of the page also overlap one another even though I'm using the prawn number_pages method
class TestReport < Prawn::Document
def to_pdf
font('Helvetica')
bounding_box([bounds.left, bounds.top - 50], :width => bounds.width, :height => bounds.height - 100) do
text 'begin'
y_pos = y
transaction do
begin
group do
64.times do|i|
text i.to_s
end
end
rescue
rollback
end
end
self.y = y_pos
64.times do|i|
text i.to_s
end
text 'end'
text page_number.to_s
end
page_numbers(1)
#render
end
def page_numbers(start)
string = "page <page> of <total>"
options = { :at => [bounds.right - 150, 40],
:width => 150,
:align => :right,
:start_count_at => start,
:color => "000000" }
number_pages string, options
end
end
def test_report
pdf = TestReport.new()
pdf.to_pdf
send_data pdf.render, filename: "test.pdf",
type: "application/pdf",
disposition: "inline"
end
The problems seem to be with transaction rollbacks. The main thing I want is to be able to use the group method. Is there another way?
Is my code wrong? Am I missing something or do transaction not currently work.
I'm currently using the master prawn branch in a ruby on rails application ( gem 'prawn', :git =>
'git://github.com/prawnpdf/prawn.git', :branch => 'master').
This question is quite old now, but I'll post an answer since it is one of the first hits on Google when searching for the exception.
Transactions still doesnt work with page breaks (v 1.0.0.rc2), so I created a helper method that tries to use grouping first and then if the exception occurs it just retries without grouping, making the content span more than one page.
def group_if_possible(pdf, &block)
begin
pdf.group { block.call }
rescue Prawn::Errors::CannotGroup
block.call
end
end
Example: Using it when creating a table:
group_if_possible(pdf) do
pdf.table(rows)
end
EDIT:
Grouping were removed from Prawn 1.x but there is an unofficial grouping gem that works well for Prawn 2:
https://github.com/ddengler/prawn-grouping
Looks like Brad Ediger answered your question on Google Groups, but for the benefit of anyone else looking for help with this, here's his response:
Sadly, transactions do not yet work correctly when they start new
pages or change the pages collection. It's a known issue:
https://github.com/prawnpdf/prawn/issues/268
-be