Social Media
More About This Website

My name is Wayne Robinson and I'm a web applications developer from Queensland, Australia. In August 2005 I discovered Ruby on Rails and instantly fell in love. From that point forward, Ruby on Rails has been my language of choice for new projects however, I still use PHP to maintain some legacy applications.

Categories
Login
Wednesday
Oct242007

GMail Now Supports IMAP

It's been a long time coming (and I haven't yet seen an official announcement by Google) but IMAP is now supported in GMail and I can now change the way I handle backing up of my GMail account (and back up everything that I received/sent before implementing the forward-to-backup implenentation).

If you don't believe me, see the "Forwarding and POP/IMAP" tab now available in GMail's settings. 

Thursday
Oct112007

All My Funds - Low-cost Subscription-based Superannuation

As everyone may have noticed, I haven't been posting a huge amount over the last 12 months, but there has been a reason. We have just launched All My Funds, a low-cost subscription-based superannuation service.

All My Funds is giving the Australian public affordable, easy-to-use services to allow them to manage their super choices provided by the Australian Government. 

We have developed a sophisticated computer-based system that allows us to provide exceptional value to assist customers in simplifying and managing their superannuation and, by automating many of these systems, we can provide these services at a fixed, annual fee; often paid directly by the super fund manager.

Three reasons to use All My Funds:

  1. A consolidation service – $165.00 (incl. GST) where AMF will arrange to transfer all of your superannuation and put into the fund of your choice (e.g., AMP, BT, Colonial First etc.), regardless of the number of funds you have (only available to subscribers). No actual payment required by you (Deducted from your Super fund)
  2. Annual subscription service where all adviser fees and trails are rebated to the YOU. The annual subscription cost is $385.00 (incl. GST) – and is deducted from your super fund – Click pie charts to the right to see why you need to do something NOW! You will see the effect of adviser fees and trail commissions can have on your super. No actual payment required by you (Deducted by your Super fund).
  3. A Superannuation Checkup Report (Statement of Advice, limited to your superannuation) for only $275.00 (incl. GST). You pay only $275.00 (incl GST). This could cost over $1,000 from a financial planner.

If you're and Australian resident and would like to find out more or sign up for any of our services, visit us at www.allmyfunds.com.au

 

Monday
Oct012007

iPhone and iPod Touch User-Agent HTTP Header

I have had the opportunity to recently get my hands on an iPod Touch specifically to do web-development to work with it's fully-featured Safari web browser.

These applications need specialised formatting for these devices (both have the same resolution screens). The easiest way to identify these phones is using the User-Agent header passed in a HTTP GET/POST request.

The iPod Touch's (firmware version 1.1.1) User-Agent field (found by writing a simple PHP page to return the $_SERVER['HTTP_USER_AGENT']) is:

Mozilla/5.0 (iPod; U; CPU like Mac OS X; en)
AppleWebKit/420.1 (KHTML, like Gecko)
Version/3.0 (Mobile/3A110a Safari/419.3

The iPhone's User-Agent field (found at note19.com's blog) is:

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)
AppleWebKit/420+ (KHTML, like Gecko)
Version/3.0 Mobile/1C28 Safari/419.3 

 The above User-Agent fields have been split over multiple lines to aid legibility.

 

Saturday
Feb172007

ActiveRecord and programmatically working with attributes.

Ruby on Rails is great. Partially because of all the ORM stuff and partially because Ruby is infitely extendable and overrideable (yes, I just made that word up).

On my current project, I have a lot of extended attributes in models that modify other attributes or even other models entirely. So, when I create new objects and assign their attributes, I would prefer the mass assignments to go through these custom mutators.

Now in Ruby, this is relatively simple. When you want to call a method within an object programmatically, you can use the #send method:

    str = "Hello world!"
    puts str.send(:size)

    Displays: 12

However, when you are performing property setting, you have to do some manipulation to the attribute name first before you can assign a value to it. For example, the code for sending the values of a hash to the corresponding mutator methods in a Person object would be the following:

    hash = {
        :first_name => "Wayne",
        :last_name => "Robinson",
        :date_of_birth => "1982-02-15"
    }

    hash.each do | key, value |
      person.send("#{key}=", value)
    end

As you can see, there is a little bit of repetition there if you have to use that in more than one place. So, I've DRYed this code into the following ActiveRecord extension. Just pop this active_record_getters_and_setters.rb file in your lib/ directory and require it in your environment.rb file with:

    require 'active_record_getters_and_setters.rb' 

You will now have three extra methods accessible to you in all your ActiveRecord objects.

ActiveRecord::Base#set(attribute, value)
    Assigns value to the mutator (setter) for attribute.

ActiveRecord::Base#get(attribute)
    Gets the value from the accessor (getter) for attribute.

ActiveRecord::Base#set_attributes(attribute_hash)
   Does an ActiveRecord::Base#set for each key/value pair in attribute_hash.

Thursday
Feb152007

Add all non-versioned controlled files to the subversion repository

Just wrote a small one-liner to add all non-version controlled files in the current path and down to a subversion repository without any unecessary warning messages or errors.

svn st | \
  grep -E "^\?" | \
  sed -e s/^\?\\s*//g | \
  sed -e s/\\s/\\\\\ /g | \
  xargs -I{} svn add {}

I have only tested this on Cygwin so far, but it should work fine on Linux and Mac OS X.

Tuesday
Feb132007

TIBCO General Interface

With all the work I've been doing with Ruby on Rails recently, I haven't given much thought to the advancements being made for web-based application development. However, yesterday I stumbled across TIBCO's General Interface.

General Interface is an AJAX GUI design framework, with it's IDE also published as a web application. It communicates with the N-tier via XML-based web services and has a very good selection of well written controls (lists, matrices, charts, etc) for embedding in your application.

I've played a little with General Interface and I'm generally blown-away by it's power and ease of use. The only two things stopping me from jumping in and doing some serious development, is the fact that it is only a GUI interaction tool and not a complete development stack. I would still need to write the N-tier somewhere (yes, I know I could publish Ruby on Rails applications as web-services only).

If you're developing web-based content for an existing application (say, Salesforce or NetSuite) and are looking for an easy to use, powerful, web-based GUI framework. I would suggest evaluating TIBCO's General Interface. Or at leaset having a look at some of their screencasts.

Saturday
Nov112006

Multiple Values from Scriptaculous' Autocomplete

Ever wanted to extract multiple values from a Script.aculo.us Google Suggest-like autocomplete text field? I recently did and here's how.

If you aren't aware of how to use autocomplete text fields, please read over the simple and customised demos available at Script.aculo.us. Also, a warning, this demo utilises Ruby on Rails however, with a little bit of modification, this should work using the Script.aculo.us library without Ruby on Rails.

This example will auto-populate a state and postcode based on the user's selected suburb (yes, I'm Australian).

The first step is to create a view for the page containing the autocomplete field and for the autocomplete field itself.

Controller:

def new
# This is the main controller that will
# contain the autocomplete field
@contact = Contact.new
end

def auto_complete_for_suburb
suburb = params[:suburb]
@surburbs = Suburb.find_by_name(suburb,
:order => "name", :limit => 20)
render :partial => "auto_complete_suburb"
end

View for the new action (assume an application.rhtml template has been created, this template must include the Prototype and Script.aculo.us javascript libraries):

<%= form_tag({:action => :create}, {:method => :post}) %>
<table>
<tr>
<th>Name:</th>
<td><%= text_field(:contact, :name) %></td>
</tr>
<tr>
<th>Suburb:</th>
<td><%= text_field_with_autcomplete(:contact, :suburb,
:select => "value",
:after_update_element =>
"function (ele, value) {
$("contact_state").value =
Ajax.Autocompleter.extract_value(value,
'STATE');
$("contact_postcode").value =
Ajax.Autocompleter.extract_value(value,
'POSTCODE'); }
") %>
</td>
</tr>
<tr>
<th>State:</th>
<td><%= text_field(:contact, :state, :size => 10) %></td>
</tr>
<tr>
<th>Postcode:</th>
<td><%= text_field(:contact, :postcode,
:size => 10) %></td>
</tr>
</table>
<%= end_form_tag %>

Before we continue any further, it is worth-while defining the _auto_complete_suburb.rhtml partial.

<ul class="suburbs">
<% unless @suburbs.nil? -%>
<% @suburbs.each do | suburb | -%>
<li>
<%= h("#{suburb[:name]}, #{suburb[:state]}" +
"#{suburb[:postcode]}") %>
<div class="value" style="display: none;">
<%= h(suburb[:name]) %>
</div>
<div class="STATE" style="display: none;">
<%= h(suburb[:state]) %>
</div>
<div class="POSTCODE" style="display: none;">
<%= h(suburb[:postcode]) %>
</div>
</li>
<% end -%>
<% end -%>
</ul>

The autocompleter view has three (3) hidden <div> tags which contain the extra data used by the base Autocompleter Javascript methods as well as the new one (extract_value) that will be defined below. 

You may also want to cast your eye over the suburb field definition in the new contact view as this is where most of the action is. There are two options to note:

  • the :value option which specifies the class name of the element which contains the value to place in attribute (the default would be whatever is within the rendered <li> field which, as we will find out below, will contain more than just the selected suburb)
  • the :after_update_element option which specifies a piece of Javascript to execute when the item is selected. You will see that this Javascript executes the Ajax.Autocompleter.extract_value function twice. This function does not exist in Script.aculo.us but is provides an easy way to extract extra values from an autocomplete list.

The Script.aculo.us Autocompleter methods conviently pass the complete contents of the <li> field to the method specified in the :after_update_element option. This allows us to extract any additional values from this data. I have created a simple addition to the Ajax.Autocompleter class below that speeds this extraction:

Additional method for Ajax.Autocompleter class. This can be declared anywhere after the inital Script.aculo.us script inclusion. For my purposes I put this at the top of my application.js file. 

Ajax.Autocompleter.extract_value = 
function (value, className) {
var result;

var elements =
document.getElementsByClassName(className, value);
if (elements && elements.length == 1) {
result = elements[0].innerHTML.unescapeHTML();
}

return result;
};

 So that's all there is to it. If anyone would like me to create a demo of the above code, ask me and, if I get enough requests, I'll put something together.