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.

No comments:

GitHub Projects