Monday, March 24, 2008

Generating unique random numbers

Interesting techniques:

Best one:
irb(main):001:0> (1..13).sort_by{rand}[0..7]
=> [7, 3, 8, 2, 11, 4, 1, 9]

Another one:

ar = []
while ar.length < 8
ar << rand(12) + 1

Friday, March 21, 2008

Ignoring files in SVN

To ignore schema.rb:
  1. Open command line and from rails root, cd db
  2. svn propset svn:ignore schema.rb .

What this means is, ignore schema.rb in the current folder. The dot at the end denotes you are ignoring something in the current directory.

Another example. To ignore all the files in the log directory:
  1. Open command line and cd to rails root
  2. svn propset svn:ignore log .
One last example. To ignore folder1 and folder2:
  1. Open command line and cd to rails root
  2. svn propset svn:ignore folder1 folder2 .

Here is a nice article that explains these in details.

Tuesday, March 18, 2008

alias_method for class methods

class Login
def self.super_user
system_admin = Role.find_by_desc("system_admin")
:conditions => "permissions.role_id = #{}",
:include => :permissions)

class << self
alias_method :system_admin, :super_user

Some links:

Loading fixtures separately

Recently I had to load one single fixture file in to the database. Here is how I did it:
>> messages = YAML.load( + '/test/fixtures/message_triggers.yml'))
>> messages.each{|m| MessageTrigger.create(m[1])}

Sunday, March 16, 2008

Date and Time Functions in MySQL

Quite often I am having to perform date and time calculations in my applications. Earlier I was doing all these things in Ruby. But later I realized these things will be faster and better if performed by the database engine. These calculations become cumbersome as they become complex. Here is a link to MySQL's date and time functions.

2 of the most commonly used functions:
  • Add an interval to a date and get back the updated date.
     DATE_ADD(s.expires_on, INTERVAL p.expiration_buffer DAY)
  • Return date in a particular format. In this case "2008-03-17"

Tuesday, March 11, 2008

Rails Gotchas: Routes

This won't work:
map.disclaimer '/disclaimer', :controller => :main, :action => :disclaimer

Whereas this works:
map.disclaimer '/disclaimer', :controller => "main", :action => "disclaimer"

The difference is: the first one contains symbols and the second strings.

Monday, March 10, 2008

Integer division

I was trying to divide 3 by 5 (3/5) and I never got the correct result. I got back 0 all the time which is obviously not correct. But when I did 6/2 I got back 3. So when I researched a little I found out that it defaults to integer division in Ruby. That means it doesn't divide the integer if the resultant is going to be a float. So I had to do this: 3.to_f/5.to_f.

An interesting discussion about this point:

Thursday, March 6, 2008

Column type mappings for databases

I always wondered how Rails maps the column types we define in migrations to appropriate data types in the database. There is no direct mapping between the data types that Ruby defines and the ones a database defines (not all at least). For example there is no string data type in any of the databases that I have worked with. I figured that today.

Here is a hash defined by mysql_adapter.rb:

def native_database_types #:nodoc:
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
:string => { :name => "varchar", :limit => 255 },
:text => { :name => "text" },
:integer => { :name => "int", :limit => 11 },
:float => { :name => "float" },
:decimal => { :name => "decimal" },
:datetime => { :name => "datetime" },
:timestamp => { :name => "datetime" },
:time => { :name => "time" },
:date => { :name => "date" },
:binary => { :name => "blob" },
:boolean => { :name => "tinyint", :limit => 1 }

If you are using a different database then look up this hash in its respective adapter. Normally adapters are named like "#{database}_adapter.rb" under '\active_record\connection_adapters".

A detailed look at Ruby Vs MySQL mappings:

Tuesday, March 4, 2008

Instlling a specific version of a gem

gem install --version '0.4' hpricot
gem install --version '1.2.6' rails

and (&&) operand

I found the following block in routing.rb of rails framework.
routes.each do |route|
result = route.recognize(path, environment) and return result

I didn't understand this block at all. So I posted this in the Ruby mailing list. The good folks at the group answered me back immediately with some good examples. Here is the link:

To summarize:
If the first operand (we can even call it a statement), i.e. result = route.recognize(path, environment) retuns true then the following things would happen:
  1. 'result' variable contains the result of the recognize statement (which is a hash)
  2. The second operand (statement) gets evaluated which in turn ends the block by returning the result variable
If the first operand returns false then nothing happens so the loop continues.

But what is tricky in the statement "result = true and x = 20" is that 'result' contains true and not 20. Which means the first operand is also doing an assignment. I initially thought result will contain 20 because that's return value of the second statement.

Here is another explanation of the same subject:

Super stuff. Ruby Rocks.