Tuesday, 19 January 2010

jQuery readonly on checkboxes

Well here is an annoying thing.
You can't set the readonly attribute to checkboxes or select. And if you set disabled="disabled" the values aren't passed in the submit.
Bum.

Fields_for, symbols and instance variables

Had a problem with fields_for and accepts_nested_attributes_for

The invoice class has many invoice items, but they have to be displayed in a certain order. Originally I had an @invoice_items variable - but the form wasn't looking at this.
However, a genius on teh Ruby forum posted the following:
@invoice = Invoice.find(params[:id], :include => :invoice_items, :order "invoice_items.display_order")

When the invoice calls the invoice_items they are already in the object and in the right place. Now he has pointed it out to me, I get what it is - but don't think I would have come up with that on my own.

Thursday, 14 January 2010

Transactions

Used them for the first time - and love them.
I have a situation where a job can have many editions. An edition has many pages. If you create a new page for a job, you must create it for every edition. Likewise if you delete a page from a job, you must delete it from every edition. You must never end up in a situation where one page is deleted from one edition, but for some reason it fails on the next one.
Enter transactions.

This is my destroy action (handled by jQuery rather than the inbuilt rails method)
def destroy
@page = Page.find(params[:id])
@pages = Page.find_all_by_job_id_and_page_name_or_no(@job.id, @page.page_name_or_no)
invalid = false
Page.transaction do
@pages.each do |page|
begin
page.destroy
rescue ActiveRecord::StatementInvalid
invalid = true
end
end
end
if invalid
respond_to do |format|
format.html { render :action => "new" }
format.js {render :text => "-1" }
format.xml { render :xml => @page.errors, :status => :unprocessable_entity }
end
else
respond_to do |format|
format.html { redirect_to(pages_url) }
format.js {render :json => @page.id.to_json }
format.xml { head :ok }
end
end
end


And it all works.

Monday, 11 January 2010

Didn't know this one

pages = Page.find_all_by_job_id(18511).collect(&:page_name_or_no)

gives me an array with just that field. Sweet.

Saturday, 9 January 2010

more on iText

Have to be able to merge pages - so playing more with iText and the following worked (eventually)

>> require 'rjb'
=> ["RjbConf"]
>> Rjb::load('/var/www/html/renaissance/lib/iText.jar')
=> nil
>> FileOutputStream = Rjb::import('java.io.FileOutputStream')
=> #
>> Color = Rjb::import('java.awt.Color')
=> #
>> Element = Rjb::import('com.itextpdf.text.Element')
=> #
>> Document = Rjb::import('com.itextpdf.text.Document')
=> #
>> Font = Rjb::import('com.itextpdf.text.Font')
=> #
>> FontFactory = Rjb::import('com.itextpdf.text.FontFactory')
=> #
>> PageSize = Rjb::import('com.itextpdf.text.PageSize')
=> #
>> Paragraph = Rjb::import('com.itextpdf.text.Paragraph')
=> #
>> Phrase = Rjb::import('com.itextpdf.text.Phrase')
=> #
>> BaseFont = Rjb::import('com.itextpdf.text.pdf.BaseFont')
=> #
>> ColumnText = Rjb::import('com.itextpdf.text.pdf.ColumnText')
=> #
>> PdfPageEvent = Rjb::import('com.itextpdf.text.pdf.PdfPageEvent')
=> #
>> PdfPCell = Rjb::import('com.itextpdf.text.pdf.PdfPCell')
=> #
>> PdfContentByte = Rjb::import('com.itextpdf.text.pdf.PdfContentByte')
=> #
>> PdfPTable = Rjb::import('com.itextpdf.text.pdf.PdfPTable')
=> #
>> PdfWriter = Rjb::import('com.itextpdf.text.pdf.PdfWriter')
(irb):18: warning: already initialized constant NAME
=> #
>> PdfReader = Rjb::import('com.itextpdf.text.pdf.PdfReader')
=> #
>> pdfTest = PdfReader.new('/tmp/test.pdf')
=> #<#:0x2b0282c08e38>
>> pdfTest2 = PdfReader.new('/tmp/test2.pdf')
=> #<#:0x2b0282c03ff0>
>> document = Document.new
=> #<#:0x2b0282c00f80>

>> pdf_writer = PdfWriter.getInstance(document, FileOutputStream.new("/tmp/merge.pdf"))
=> #<#:0x2b0282bf55b8>
>> document.open
=> nil
>> cb = pdf_writer.getDirectContent()
=> #<#:0x2b0282bef898>
>> document.newPage
=> true
>> page1 = pdf_writer.getImportedPage(pdfTest, 1)
=> #<#:0x2b0282be2b20>
>> cb.addTemplate(page1, 0, 0)
=> nil
>> document.newPage
=> true
>> page2 = pdf_writer.getImportedPage(pdfTest2, 1)
=> #<#:0x2b0282bd7a18>
>> cb.addTemplate(page2, 0, 0)
=> nil
>> document.close
=> nil
>>


NOw have a two page pdf - hurrah (again)

Friday, 8 January 2010

Playing with iText

hurrah for Hello World

In the app - I need to create a whole bunch of pdfs and then glue them all together. Having installed iText and RJB seems sensible to try and get it to work.
Playing in the console - the following actually worked

>> require 'rjb'
=> ["RjbConf"]
>> Rjb::load('/var/www/html/renaissance/lib/iText.jar')
=> nil
>> filestream = Rjb::import('java.io.FileOutputStream')
=> #
>> pdfreader = Rjb::import('com.itextpdf.text.pdf.PdfReader')
=> #
>> pdfwriter = Rjb::import('com.itextpdf.text.pdf.PdfWriter')
(irb):5: warning: already initialized constant NAME
=> #
>> pdfdocument = Rjb::import('com.itextpdf.text.Document')
=> #
>> document = pdfdocument.new
=> #<#:0x2b49dc62af10>
>> pdfwriter.getInstance(document, filestream.new('/tmp/test.pdf'))
=> #<#:0x2b49dc624430>
>> document.open
=> nil
>> pdfParagraph = Rjb::import('com.itextpdf.text.Paragraph')
=> #
>> paragraph = pdfParagraph.new("hello world")
=> #<#:0x2b49dc60cb78>
>> document.add(paragraph)
=> true
>> document.close
=> nil
>>


It opens a for real pdf with the iconic words "Hello World". Hurrah

leading zeros

This was handy

"%05d" % int

if int = 123 it will give you the string "00123"