Wednesday, July 25, 2007

Ruby on Rails - Up and Running Book Review

Recently, I've been interested in learning Ruby on Rails, but at the beginning of my quest I wasn't sure where to begin, there are a lot of documentation in the Web that I could use but I wanted some structured tutorial that guide me through my first experiences with Rails.

Fortunately, the company where I work bought the book Ruby on Rails Up and Running by Bruce A. Tate and Curt Hibbs, so I took it and started reading it and what I found was exactly what I was looking for, a beginners book.

I give this book 4 starts because I think it's really good for someone who is just starting to learn about Rails. It explains the basics of the language and the authors use the same example along each chapter so you can learn all the concepts in the book in a very practical way. The example is a Photo Slideshow application, a very common example actually because it allows you to develop some business logic along with interesting views handled by Ajax and some Javascript effects.

With this book, you can learn the basics of Active Record and Active Record Relationships, Scaffolding, Views, Migrations, Ajax and a bit of Testing.

It is not too long, so you won't feel intimidated by it. It is a good place to start, trust me!

I recommend it!

How to handle Time fields in MySQL and Ruby on Rails

One of these days while I was working in a small application created in Ruby on Rails I came across a field in the database with data type Time. The interesting thing was that Rails does not support Time fields, it supports only Date or Datetime, so what to do?

Since I had to handle Time fields not dates, I had to do some tricks to make this work. I'm going to share with you, in a high level, what I did.

First, in the RHTML page I handled the time (hour and minutes) using my own fields, maybe HTML selects with the possible time values.

Next, I created some Javascript function which would post the time as a String or numeric value to the controller, then in the controller you convert the value to a String notation with the format "HH:MM", for example "08:30" or "14:25".

Then, you create a Ruby Time object using your String time as follows:
timeObj = Time.parse("8:15")

This will create a Time object with the current system date and the given hour and minutes you set.

Finally, when you store your Time object in database, MySQL will truncate the date and store only the time value which is exactly what you wanted to do in the first place.

I hope this helps!!

Prototype Javascript Framework - Creating classes

Here it is a quick review of how you can implement classes in Javascript using the Prototype Framework. (This was taken of the Prototype reference document that you can find in http://beta.bigmedium.com/projects/prototype-pdf/index.shtml)

If you are familiar with Object Oriented Programming, handling classes in Javascript would be really easy and Prototype makes easier.

Another advantage of using classes in Javascript is that you can have cleaner code, easy to use and maintain.

I'll show you now how to create a class using Prototype.

create() -> Function

Returns an function that acts like a Ruby class.

Class.create() returns a function that, when called, will fire its own initialize method.It also lets you more easily subclass by overriding a parent's constructor.

Example:

var Person = Class.create();
Person.prototype = {
    initialize: function(name, lastname, age) {
         this.name = name;
         this.lastname = lastname;
         this.age = age;
     },
     myAge: function() {
         alert("My age is " + this.age);
    }
};

var john = new Person("John", "Doe", 25);
john.myAge();
// -> alerts "My age is 25"

var Employee = Class.create();
Employee.prototype = Object.extend(new Person(), {
     initialize: function(name, lastname, age, job) {
         this.name = name;
         this.lastname= "lastname";
         this.age = age;
         this.job = job;
     },

     myJob: function() {
         alert("I work as a " + this.job);
    }
});

var susan = new Employee("Susan", "Smith", 30, "Teacher");
susan.myJob();
// -> alerts "I work as a Teacher"

Friday, July 13, 2007

Prototype Javascript Framework - Utility Methods

Here it is a quick review of the most important utility methods of the Prototype Framework. (This was taken of the Prototype reference document that you can find in http://beta.bigmedium.com/projects/prototype-pdf/index.shtml)

$

$(id | element) -> HTMLElement
$((id | element)...) -> [HTMLElement...]

If provided with a string, returns the element in the document with matching ID; otherwise returns the passed element.

The function also extends every returned element with Element.extend so you can use Prototype's DOM extensions on it.

$$

$$(cssRule...) -> [HTMLElement...]

Takes an arbitrary number of CSS selectors (strings) and returns a document-order array of extended DOM elements that match any of them.

The $$ function searches, by default, the whole document.

Current set of supported selectors:

  • Type selector: tag names, as in div.

  • Descendant selector: the space(s) between other selectors, as in #a li.

  • Attribute selectors: the full CSS 2.1 set of [attr], [attr=value], [attr~=value] and [attr|=value]. It also supports [attr!=value]. If the value you're matching against includes a space, be sure to enclose the value in quotation marks ([title="Hello World!"]).

  • Class selector: CSS class names, as in .highlighted or .example.wrong.

  • ID selector: as in #item1.


$A

$A(iterable) -> actualArray

Accepts an array-like collection (anything with numeric indices) and returns its equivalent as an actual Array object.

$A doesn't perform DOM extensions, since the array could contain anything (not just DOM elements).

$F

$F(element) -> value

Returns the value of a form control. This is a convenience alias of form.Element.getValue.

$H

$H([obj]) -> Hash

Creates a Hash (which is synonymous to “map” or “associative array” for our purposes).

A convenience wrapper around the Hash constructor, with a safeguard that lets you pass an existing Hash object and get it $F | 5 back untouched (instead of uselessly cloning it).

$R

$R(start, end[, exclusive = false]) -> ObjectRange

Creates a new ObjectRange object. This method is a convenience wrapper around the
[ObjectRange](/api/objectRange constructor, but $R is the preferred alias.

$w

$w(String) -> Array

Splits a string into an Array, treating all whitespace as delimiters. Equivalent to Ruby's %w{foo bar} or Perl's qw(foo bar).

Try.these

Try.these(Function...) -> firstOKResult

Accepts an arbitrary number of functions and returns the result of the first one that doesn't throw an error.

document.getElementsByClassName

document.getElementsByClassName(className[, element]) -> [HTMLElement...]

Retrieves (and extends) all the elements that have a CSS class name of className. The optional element parameter specifies a parent element to search under.