Archive for the ‘Programming Languages’ Category

The Basics of REST in Rails

{Tuesday, April 24th, 2007}

REST fundamentals

HTTP supports 4 request (method) types:

  • Post: Intended to create a resource
  • Get: Intended to retrieve a resource
  • Put: Intended to update a resource
  • Delete: Intended to delete a resource

However browsers typically only support Post and Get requests. Put and Delete requests have been ignored and fulfilled by abusing Post and Get. The essence of REST lies in considering the web as providing information about resources, it proposes to change the way we view URL’s from actions to requests on a resource. Actions that were once part of the URL (i.e. /products/show/1), are now expressed in the method (HTTP GET /products/1).

Why should I use REST?

The key reasons appear to be:

  • As an alternative to Web Services, Messaging etc. for manipulating a resource
  • A consistent approach to resource discovery

Also consider that the cost of implementing RESTful requests in Rails is no more than conventional requests.

Rails Support

Rails accommodates the lack of browser support for Put and Delete with an additional request parameter that simulates the request type.

routes.rb is the key

The core of Rails’ REST support lies in routes.rb. As always, entries here map URL’s to controllers and actions.
The following entry allows the Product model to be accessed as a RESTful resource.

map.resources :products

These entries also generate methods used to assemble URL’s in views and controllers. Based on the previous example the following methods are generated:

  • products_url, products_path
  • product_url(id|product), product_path(id|product)
  • new_product_url, new_product_path
  • edit_product_url(id|product), edit_product_path(id|product)

They can be used as follows:

  • Link to list all Products
    link_to 'Products', products_path
  • Form for creating a new product
    form_tag(:product, :url => products_path) do
  • Form for editing a product
    form_tag(:product, :url => product_path(@product), :html => {:method => :put}) do
  • Link to delete a Product
    link_to 'Delete', product_path(@product), :method => :delete
  • Performing a redirect to view a Product
    redirect_to product_url(@product)

Controllers respond via respond_to

REST allows clients to request different response types. Controller actions accommodate this using respond_to. Example:

def show
  all_product = Products.find :all
  respond_to do |format|
    format.html
    format.xml render(:xml => all_products.to_xml)
  end
end

To issue a non-HTML RESTful request the URL must be a RESTful URL ending with .<desired type>. For example a XML request should end in .xml (i.e. METHOD GET /products/1.xml).

Scaffold support

Rails scaffolding supports the use of REST:

rake scripts/generate scaffold_resource <name> <field>:<type> <field>:<type>...

This command

  • Creates: model, restful controller, views, migration with columns
  • Edits: routes.rb for RESTful request support

SQL Refresher: Joins & Aggregates

{Monday, April 23rd, 2007}

My memory on some SQL features often gets hazy until they’re needed by a project that demands those skills. This blog serves as a recall aid - hope you find it useful also.

Inner Join

Returns only rows that have a key match in both tables. Typically a join that does not use inner/outer notation is implicitly an inner join.
An inner join is also known as an Equi-Join.

Example: List all employees of an organisation who have been assigned to a division

select e.name, d.name
from employees e
inner join divisions d on e.division_id = d.id

Outer Join

There are 3 types; Left, Right and Full. They ensure all rows from one or both tables are present in the result set.

Left Outer Join

All rows in the left table are included in the result regardless of a key match with the right table.

Example: List all employees of an organisation regardless of whether they are assigned to a division

select e.name, d.name
from employees e
left outer join divisions d on e.division_id = d.id

Right Outer Join

The reverse of a left join, all rows in the right table are included in the result regardless of a key match with the left table.

Example: List all divisions of an organisation regardless of whether they have an employee assigned

select e.name, d.name
from employees e
right outer join divisions d on e.division_id = d.id

Full Outer Join

Combines a Left and Right Join, all rows in both tables are included in the result regardless of a key match.

Example: List all employees and divisions of an organisation

select d.name, e.name
from divisions d
full outer join employees e on d.id = e.division_id

More on Joins: Wikipedia. Note Natural Joins are similar to Inner Joins and Cross Joins perform a cartesian product.

Group By

Aids removing redundant results when aggregate functions are performed.

Example: List the total cost of orders

select sum(cost) as total
from purchase_items
group by order_id

Having

Facilitates adding selection criteria to aggregate columns in a result set.

Example: List the total cost of orders with a minimum spend

select sum(cost) as total
from purchase_items
having total > 100

Rails Binaries Install

{Monday, April 16th, 2007}

I’ve traditionally installed Ruby, RubyGems and Rails via installers. Far a laugh, I thought I’d try it from binaries but I found the experience a bit rough on the edges.
Here’s some problems I encountered with workarounds - if anyone has nicer alternatives drop me a line.

RubyGems install: No such file to load — ubygems (LoadError)

To install RubyGems it’s recommended to execute

ruby setup.rb

after extracting the gems archive (more details can be found here).
First time I tried this I encountered this problem. Turns out the cause of this was some legacy environment variables lying around from an old install, as detailed here. So I removed RUBYOPT and tried again.

RubyGems install: zlib.dll not found

Second time I executed ruby setup.rb this problem surfaced. I downloaded the dll via zlib.net, renamed the dll from zlib1.dll to zlib.dll, placed it in the ruby/bin directory and tried again.
Viola! Success! RubyGems setup complete.

Rails install: Could not find rails (> 0) in any repository

When attempting to install rails I received this error. Google told me this was the most common solution, but the last comment was the winner.
Run gem install rails -y the second time and you’re done.

Rails console startup: readline.dll not found

Yet another dll missing! On this occasion Google said download the readline package for windows and do the right things with the dll.
Viola!

For what it’s worth I can handle the first problem, but the others seem a tad unnecessary.