Friday, June 30, 2006

More Getting Real

37 Signals keep banging on about 'getting real' or making small things that work well with small teams. Paul Graham has a great post on his blog called The Power of the Marginal. His writing style is great. There were more than a couple of places that made me giggle.

Thursday, June 29, 2006

What do you mean, 'What's Rails?'

Through a conversation with a .Net buddy of mine it became apparent that not everyone knows what Rails is...so .. Here is my 1 min pitch for developers.

Ruby on Rails (or just Rails for short) is a web development framework built on the MVC architecture. Ruby is an inturpreted implicitly typed language that the framework is written in.

M is for model

The beauty of the Ruby programming language is how easy it is to extend the language to create other domain specific languages (DLSs). This is used in Rails to create a DSL for defining strongly typed domain objects (model) that also automagically works as your DAL (data access layer) by mapping each class to a table and each instance of the class to a row (i.e. using the Active Record design pattern).

class Person < ActiveRecord::Base
end

That is enough code to give you a Person class with a 'find' method that will load instances from the 'Persons' table in the database, and properties for each column in the database.

So... you can do:
p = Person.find (1)
p.name = 'nigel'
p.save

... to change the name of the person with id=1 to 'nigel'.

class Person < ActiveRecord::Base
has_many :blogs
belongs_to :family
validates_length_of :name, :maximum= > validates_numericality_of :age
validates_presence_of :family
end


would add methods to the class to allow you to navigate the relationships to joined tables. The lovely part is that this class is just a class, so you can add whatever business logic to it you want to add and it all just works. You can hook into events like validate, save, etc. and put in custom code too.

V is for view

The View is provided by an ASP-like templating system called 'rhtml'. Basically its just HTML with ruby sprinkled through it. Again the versitility of ruby makes this painless to use. (There are other solution to the view for Rails, but this is the default)

so... app\Person\edit.rhtml might be..


<h1>Edit Person<h1>
<%= start_form_tag :action =>'update' %>
<%= error_messages_for 'person' %>
<p>
<label for="person_name">Name</label>
<%= text_field 'person', 'name' %>
</p>
<%= submit_tag 'Edit' %>
<%= end_form_tag %>

... which will create a form with a post action of '\person\update\1' (where 1 is the ID of the record being edited) passing the form fields (name in this case) as post fields.

To avoid duplication you have 'layouts', 'partials', and 'helpers'.. (not covered here)

C is for controller

The Controller is where your code kicks in to handle each web request. The requested url is put through some customizable routing code, that by default causes a method to be called on a controller passing a 'params' hashtable of values from the form. By default there is a view associated with each method of the controller.

So for example :

http://www.example.com/people/edit/1 would cause an instance of the 'PeopleController' class to have its 'edit' method called passing in a hash containing id=1.

Typical code inside the controller would then call '@person = Person.find(params[:id])' setting a local variable 'person' to the instance of the active record class Person that is retrieved from the database.

The framework would then by default render the associated view 'app\views\people\edit.rhtml' automatically populating the 'text_field' with the value of @person.name. The user can then change the name and click 'Edit' to trigger the form to post the new vaules. These are then fed in a params hashtable to the PeopleController class again where the 'update' method is called (as it is the action of the form). Some simple code in the PeopleController like ...

def update
@person = Person.find(params[:id])
@person.update_attributes(params[:person])
end

... is enough to save the new values back to the database.

You would probably want to do something like this instead though...

def update
@person = Person.find(params[:id])
if @person.update_attributes(params[:person])
flash[:notice] = 'The person was sucessfully updated.'
redirect_to :action = 'show', :id = @person
else
render :action = 'edit'
end

end


Any validation erros would then cause the user to be sent back to the same edit form with validation errors displayed. Yes, magically (see the "error_messages_for 'person'" line).

ok thats enough to get you started I'm sure, and I havent even touched on migrations, or ajax support, or the built in testing fixtures. Google for 'Ruby on Rails', or check out http//www.rubyonrails.org/ for more info.

Happy Railing.

Ruby on Rails just keeps getting cooler

DHH's latest extensions to Rails take advantage of the CRUD nature of the HTTP protocol to make URLs more powerful. A recent extention to the routing system allows you to base your rules on the HTTP method {GET, POST, PUT, DELETE} aswell as the url of the request. This opens up the possibility of calling several different controller methods from the same URL.



This has several beneficial results.

Check out DHH's slides for some more info.

Note: Most proxy servers don't handle Put and Delete methods correctly, so DHH has put in a work around using Post and some hidden form fields.

Wednesday, June 21, 2006

RailsDay: 24 hours of solid Railing

Myself and a couple of friends (Craig and Simon Hildebrandt) spent 24 hours straight coding Ruby on Rails. We met up at a house in the city and coded from 2pm Saturday to 2pm Sunday. There was however method to out madness; we were competing in 'Rails Day 2006'.

We wanted to create something that we would find valuable in our own projects, and that we could use over and over again, and I am happy with the result.

The aim was to create, what will eventually become an engine, that will allow us to create custom CRM solutions for a fraction of the development time.

Our submission to the Rails Day contest looks like a very simple CRM application. Admin users are presented with a very simple/clean/intuitive interface to modify any data in the database, including relationships (task 1 belongs to a project 2, etc.). The Magic is that the whole admin section is auto-generated directly from the model, no coding required.

The admin controller looks for model classes and adds then to the list of editable types. For each type is displays a list of all instances and an edit/create form. It uses information from the column type and validation rules to decide which widget is required for each attribute of the model object. 'belongs_to' relationships are displayed as drop downs. 'has_many' is displayed as a list with an 'add to list' widget. We also demonstrated that this can be extended to account for 'acts_like' mix-ins and plug-ins by handling the 'file-column' plug-in.

We are hoping that by open-sourcing this projects we will be able to get people to extend the number of plug-ins, acts_like's, validation rules, etc., that the framework handles.

Already we are finding this engine valuable in our own projects, soon, I hope, you will in yours.

... keep watching for a rubyforge link soon...

Cheers,
Nigel

Thursday, June 15, 2006

Fed up with blogger

I am going to move my blog. Blogger keeps loosing my account so I can't log in.

GitHub Projects