Wednesday, January 2, 2008

Radio Buttons

RoR is lovely when it comes to supplying frontend helpers. For example, if you want to create a form for a particular object, it's very simple:

<% form_for :user, :url => new_user_path do |f| %>
...
<% end %>

Inside "...", you can add all your fields, such as:

First name: <%= f.text_field :first_name %>
Last name: <%= f.text_field :last_name %>
...
<%= submit_tag 'Update' %>

This creates a form using the user object. It fills in the first and last names using the data found in the user object. If the user object is new, then the text fields are empty. If the user object is from database, then that information is displayed. Pressing the submit button submits the form to the specified url. It's very simple! There are helpers do to all sorts of things, such as text areas, selects, date selects, time selects, checkboxes, etc. Check the API for more helpers.

However, our topic for today is actually radio buttons. Many times, we want to use radio buttons to select some sort of true/false field. It is possible to do this with checkboxes, andRoR is wonderful with this. However, sometimes, 2 radio buttons are better. This is where I ran into some problems. Reading the API, I came up with 2 radio buttons as follows:

<%= f.radio_button :is_good, true %>
<%= f.radio_button :is_good, false %>

I thought that this would generate two radio buttons with values true/false respectively. However, it didn't! The first generated one that had a value of "true" and was checked. But the second generated a radio button with no value! I then changed the given values from booleans to strings:

<%= f.radio_button :is_good, 'true' %>
<%= f.radio_button :is_good, 'false' %>

Everything worked fine now, but given a model that held data, neither radio buttons were checked! This is due to the fact that the model holds boolean values, whereas the radio buttons use string literals. Saving was fine because we were using prepared statements, which automatically convert the string literals to boolean. I was completely stumped on the displaying of data though. I came up with a quick hack using virtual attributes, but it's ugly:

def is_good_temp=(is_good_temp)
@is_good_temp = is_good_temp
if @is_good_temp == 'true'
self.is_good = true
else
self.is_good = false
end
end

def is_good_temp
@is_good_temp.nil? ? 'true' : @is_good_temp
end

def is_good
@is_good.nil? ? true : @is_good
end

def is_good=(is_good)
@is_good = is_good
end

and changed the radio buttons to:

<%= f.radio_button :is_good_temp, 'true' %>
<%= f.radio_button :is_good_temp, 'false' %>

So basically what I did was create a virtual attribute to deal with the radio buttons using string literals, and have that convert the string literals to booleans and assign it to the actual variable. To be noted is that there is no nice function object#to_b to convert a string literal to boolean. There are nice functions like object#to_s and object#to_i, but not to boolean.

This is one disappointment from RoR. I have searched around and could find no solution to this. Perhaps I am doing this wrong, but for now, it works.

Any ideas would be appreciated, and I'll update if I find a better solution.


W

Wednesday, December 19, 2007

Introducing Rails 2 - Part 1.5

For those who have tried to install rails 2.0 and find it acting all weird afterward. It's probably because you updated rails with an out of date rubygem

if you are having trouble with rails 2.0, you can do a quick check on your rubygem by typing

gem --version

If it's version 0.9.4 or below, then you should update your gem and reinstall rails. You can update rubygem with the following command

gem update --system

This might take awhile, so be patience. After it's done, check the version again by doing

gem --version

and make sure it's at version 1.0.0. Now you can reinstall rails 2.0 by typing

gem install rails --include-dependencies

There's a problem with the old gem, it will only install the rails core for you but skipping ActiveRecord, ActiveResource, and Rake

For those who have an existing project, go into environment.rb and make the following change

RAILS_GEM_VERSION = '2.0.2'

give this a try, it works for me


J

Monday, December 17, 2007

Introducing Rails 2 - Part 1

W and I have decided to upgrade to rails 2.
All you need to do is to type in this command in your command prompt

gem install rails -y --source http://gems.rubyonrails.org

and ruby gem will handle the rest.
After the upgrade is completed, type

rails -- version
to check if it's 2.0.1
and that's it, you are done :)

So before we look at all the new features in rails 2, let's first find out
what has been removed.

1. @params should be replaced with params
eg: params[:data] instead of @params[:data]

the same goes for @flash, @session, @env, and @request

2. find_all & find_first should be replaced with find(:all) & find(:first)
eg: User.find(:all) instead of User.find_all
User.find(:first) instead of User.find_first
note: User.find_by_xxx is still valid

3. acts_as is gone
they are plugins now

4. render_partial should be replaced with render :partial
eg: render :partial => "user" instead of render_partial "user"

5. start_form_tag and end_form_tag should be replaced with form_for or form_tag

you can check out the api description here
http://api.rubyonrails.com/classes/ActionView/Helpers/FormHelper.html#M000920

6. Pagination is gone
mainly cause it sucks (slow)

on the bright side, there are faster and cleaner pagination plugins available
the one I'm currently using is called will_paginate and it can be found at
http://rock.errtheblog.com/will_paginate


7. components are gone

8. Database adapters are gone
you can download the one you need at
http://svn.rubyonrails.org/rails/adapters/

if you are planning to upgrade, go through your codes
to make sure it's rails 2 compatible.

if you are not sure, you might want to upgrade to rails 1.2.6 first,
where they marked everything that will be removed as a deprecated function.


J

Debugging

So the debugging that comes packaged with RadRails is a little bit slow... well, not even a little bit slow, it's tremendously slow! I had run the debugger before, and I guess I was doing some simple debugging and so I didn't notice the time it took to start and debug (or maybe I just expected it to be slow?).

Anyways, I was running some new test cases and they were failing when they should have been working. So, I pulled out my trusty debugger, and lo and behold, it took so long that I left and came back about 5 minutes later and it was still running! I ended up stopping it, as my friend, J, had reported a similar problem earlier. He told me about some sort of fast-debugging gem. I quickly googled it and found a gem that works with RadRails.

Instructions can be found here:

http://www.aptana.com/docs/index.php/Fast_Rails_Debugging_using_Aptana_Rails_IDE

If you ever need to debug, a huge time-saving suggestion would be to install this gem and use it!


W

Monday, December 10, 2007

Getting the Year from a Date Column

So I was running our unit tests that we had created after moving to PostgreSQL, and I found a database specific error. I am so thankful for our unit tests now. Instead of testing the application by hand, all I had to do was click the mouse button. I can't stress enough how important tests are.

Anyways, what I had in my code was a specific call to a MySQL function called YEAR(). This apparently was not supported by PostgreSQL. After doing some searching, I found another SQL function called EXTRACT. This seems to be supported in several databases including MySQL, PostgreSQL, and Oracle(9i, 10g, 11g).

For my purposes of getting the year, I used:

EXTRACT(YEAR FROM date_column)

More information about the EXTRACT function can be found here.

Hopefully this helps anyone having database portability problems!


W

Sunday, December 9, 2007

PostgreSQL

RoR is amazing! I love how everything is so encapsulated! After doing another project where I switched from MySQL to PostgreSQL, I wanted to try out PostgreSQL with RoR. Usually, this means a lot of backend changes and porting SQL scripts.

However, with RoR, it requires very little changes. Firstly, your whole entire database structure is created using the migration scripts. Since the migration scripts are written in Ruby, nothing has to change about these scripts. Any database access from your application do not need to be changed since they are also in Ruby. Then you must be asking, "What needs to be changed?" Very simple, the database.yml needs to be changed. Actually, only 1 line of it. This is the configuration file that RoR uses to access the database. Just change:

adapter: mysql

to

adapter: postgresql

That's it! Really, that's it! Well, actually, no... you need to install the Ruby gem that handles PostgreSQL. Since I'm developing on a Windows machine, I just enter:

>gem install ruby-postgres

For more information, you can visit this page:

http://wiki.rubyonrails.org/rails/pages/PostgreSQL

And truly, that's it. If you don't believe me, give it a try! Changing your database couldn't be easier!


W

Saturday, December 8, 2007

Back to Fun

So I'm back from my short hiatus... and one definite problem I see off the bat is... I practically forgot what I was doing before my leave... Well, that's just interesting. It took me a day or two to re-orientate myself and get back into things. Lesson learned: Before leaving something that you're halfway through, leave notes for yourself to remind you what you were doing... cause really... we all have a little alzheimer every so often.

Now that I'm back into things, this blog should be a little more colourful again. Stay tuned!


W