Polymorphic forms…

I’m currently working on a Ruby on Rails project where both the User + Company models both have addresses. It seemed fairly straight forward then that to keep my database nice and DRY I should create an address table that holds a reference to both the user and company table.

My first impression was that they were going to be quite difficult to implement as there seems to be a lot of tutorials that show and explain how to set them up in the model but nothing about how to use them in the controllers and views. I did a good bit of googling and didn’t find a lot of help.

I was pleasantly surprised however at how simple Rails makes it to set-up. Firstly you just set-up your models.


class Company< ActiveRecord::Base
  has_one :address, :as =>; :addressable, :dependent => :destroy
end

class User < ActiveRecord::Base
  has_one :address, :as => :addressable, :dependent => :destroy
end

class Address < ActiveRecord::Base
  belongs_to :addressable, :polymorphic => true
end

Next create the Addresses table to hold your addresses.


class CreateAddresses < ActiveRecord::Migration
  def self.up
    create_table :addresses do |t|
      t.string :street_address1, :null => false
      t.string :street_address2
      t.string :city, :null => false
      t.string :region, :null => false
      t.string :postcode, :null => false, :limit => 55
      t.integer :addressable_id, :null => false
      t.string :addressable_type, :null => false

      t.timestamps
    end
  end

  def self.down
    drop_table :addresses
  end
end

Next the controller. You only need to amend the ‘new’, ‘create’, ‘edit’ and ‘update’ actions in your controller to see the address fields and update the Addresses table where necessary.


class CompaniesController < ApplicationController

  def new
    @company = Company.new
    @company.address = Address.new
  end

  def edit
    @company = Company.find(params[:id])
	@company.address = Address.new unless @company.address != nil
  end

  def create
    @company = Company.new(params[:company])
	@company.address = Address.new(params[:address])

    if @company.save
	  @company.address.save
      flash[:notice] = 'Company was successfully created.'
      redirect_to(@company)
    else
      render :action => 'new'
    end
  end

  def update
    @company = Company.find(params[:id])

    if @company.update_attributes(params[:company])
	  @company.address.update_attributes(params[:address])
      flash[:notice] = 'Company was successfully updated.'
      redirect_to(@company)
    else
      render :action => 'edit'
    end
  end
end

Finally the last thing to get the address working is the form. For this I user the fields_for method. I’m using a custom form builder (Recipe 30 - Advance Rails Recipes) to build the labels and <li> tags into my form. On a side note I also only found out doing this that the form builder works nicely with the fields_for tag and not just the form_for.


<% form_for(@company, :builder => ErrorHandlingFormBuilder) do |f| %>
	<%= f.error_messages %>
<dl>
		<%= f.text_field :name %>
		<%= f.text_field :telephone %>
		<%= f.text_field :fax %>
		<%= f.text_field :website_url %>
	</dl>

	<% fields_for(@company.address, :builder => ErrorHandlingFormBuilder) do |address_fields| %>
		<%= address_fields.hidden_field :addressable_id %>
		<%= address_fields.hidden_field :addressable_type %>
<dl>
			<%= address_fields.text_field :street_address1 %>
			<%= address_fields.text_field :street_address2 %>
			<%= address_fields.text_field :city %>
			<%= address_fields.text_field :region %>
			<%= address_fields.text_field :postcode %>
		</dl>

	<% end %>
<% end %>

Once thats done everything should work, it’s fairly straight forward to get working. Next thing to do might be to extend the functionality and allow companies to have multiple addresses, which would certainly complicate matters in the form, but I might leave that for a while.

sIFR alternatives…

I’ve been using sIFR a lot recently to display some nice fonts lately. While using sIFR lately I’ve found a few alternatives to the main sIFR library.

Firstly probably one of the most useful for myself is the sIFR jQuery plug-in, this is an excellent plug-in and if you’re already using jQuery on your site will save you a decent amount of bandwidth.

A completely new alternative to sIFR is typeface.js, I’ve not entirely sure on the ins and outs of this one but it’s like sIFR without the Flash. It instead uses your browsers SVG capabilities. You have to place your font into a builder of some sort and it gets output as a javascript file. It doesn’t seem as compact and neat as sIFR but it’s still very new and worth keeping an eye on to see how it develops.

It’d be interesting to see how sIFR develops if it was ported over to ActionScript 3. The new Text Layout Framework from Adobe would give developers alot more power over the text being displayed.

Missing Monkey Island…

Lately I’ve been doing a fair bit of research into Adventure Games, during my childhood (the early 90’s) these were probably my favourite types of games, both the Discworld series and Monkey Island series. The narratives in these games were always very engrossing, the puzzles were sometimes quite taxing but generally involved you using a lot of imagination (especially when combining 2 items in your itinerary), and the graphics were very comic book. I could spend hours upon hours playing them with friends and not get bored.

A little bit of research online and I discovered ScummVM, this is an open-source program that allows you to run all the classic point-and-click adventure games on various different platforms. This really caught my eye when I saw that there was an iPhone specific version of ScummVM http://wiki.scummvm.org/index.php/IPhone, though you do have to ‘jail-break’ your iPhone for this to work (mines still quite new so I’m not yet comfortable with the idea of jail-breaking it). This is pretty exciting as the first 3 Monkey Island games as well as Day of the Tentacle are already playable on this version.

Adventure games done seem nearly as popular today as they were in the mid 90’s, but I did come across a few modern versions. Firstly was Telltale Games who have brought back the classic Sam & Max games and also have done a couple of the CSI games (I’ve not played them but always been interested being a CSI fan). On their site it says they’re going to bring out a Wii version of the Sam & Max series, which would be very cool so I might hold off buying the PC versions. Secondly was Zack & Wiki: Quest for Barbaros’ Treasure for the Wii also. This game looks like it’ll have all the classic elements of adventure games but with some cool 3D graphics and the ability to play while sitting on your sofa.

One thing I found quite amazing whilst searching for information about Adventure Games was the lack of any real framework. Lassie seemed good, although very restrictive and written in ActionScript 2. There is an ActionScript 3 version in the works however which is worth keeping an eye on.

To me it seems like it would be the perfect platform for adventure games, there’s plenty of professional animators now using flash for character animation. Flash is more than capable to handle the programming it would take to build a fully functioning adventure game engine.

I then came across this post on Andrew Langley’s blog which has a lot of information on building an adventure game in Flash, he’s even gone as far as to create a demo (very cool and works exactly how I remember the old Monkey Island & Discworld games worked) and posted some excellent code examples. The toughest thing in his examples looks like the walking boxes. These are the spaces a character can walk in any given room, there’s a lot of information being processed and looks like something that would definitely take a good few hours of solid concentration.

A complete Flash adventure game engine is something I’m definitely interested in and is something I’m going to continue to explore…

Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing.

A little something about you, the author. Nothing lengthy, just an overview.

A little something about you, the author. Nothing lengthy, just an overview.