I attended the Red Dot Ruby Conference this year at NUS University Cultural Centre last Friday and Saturday. It was a two days event and attracted approximately 200 programmers around the world.

Llya Grigorik from google gave a very interesting talk on how to build a faster web using various technics. If you are experiencing slow website problem, you may want to check out his slides at Building a Faster Web.

There are also a lot of interesting topics that were discussed during the conference e.g PUBSUB infrastructure, Client Slide Templating, Using Redis to improve site performance, CoffeeScript etc.

Red Dot Ruby Conference 2012

Red Dot Ruby Conference 2012

Cross Domain Ajax Request is something that is prohibited by the browser becomes it violates the Same Origin Policy. According to wikipedia, the term “origin” is defined using the domain name, protocol, port number. Two resources are considered to be the same origin if and only if all these values are exactly the same. This also implies that even if the two resources are in different subdomains, it is not allowed as well.

In order to do cross domain ajax request, there is one way to do it using JSONP. JSONP, which is short for “JSON with padding” is a complement to the base JSON data format. It provides a method to request data from a server in a different domain. This is viable because there is no restriction on including third party javascript files in the website. So here is how it works. E.g. you are requesting a server http://sampleserver.com/sampledata.json to return the following json

{ "name" : "Shanison" }

Instead of directly requesting this using XMLHttprequest, you use javascript to insert a script tag in the html,

Now the browser would send the requests and download the response, but the problem is that the response is JSON instead of javascript. So the trick here is that for server instead of returning JSON, it returns a function call with the JSON:

callBack({ "name" : "Shanison" })

After the javascript is downloaded, it will call the method callBack, which will takes the JSON as a parameter. Inside this callBack method, you can get the response of the JSON and do what ever you want.

So if you are using RAILS and JQuery, here is what you can do. Jquery provides a way to directly call ajax with JSONP as requested dataType and you don’t have to do the things as create a call back methods and create the script tag and inserted into the html. If you use jQuery, this is what you normally do ajax Request:

    $.ajax({
      url     : 'http://sampleserver.com/sampledata.json',
      type    : 'GET',
      dataType:  'json',
      success : function (response) {
        if (response['success'])
        {
          loadData(response['html']);
        }
      }
    })

To change it to use jsonp, you just need to change the dataType to ‘jsonp’, everything else remains the same. Jquery will do the magic I described for you. At the same time, it will send a parameter ‘callback’ to the server, which is the call back methods name that is generated by jQuery, it is a random name.

    $.ajax({
      url     : 'http://sampleserver.com/sampledata.json',
      type    : 'GET',
      dataType:  'jsonp',
      success : function (response) {
        if (response['success'])
        {
          loadData(response['html']);
        }
      }
    })

Now the only thing needs to be changed is on the application server. The application needs to make sure the response can return JSONP instead of JSON. If you are using Rails, to render the response in JSON, you usually do:

render :json => {:success => true, :html => prices_html}

To render the response with JSONP, which would wrap the JSON with the callback method submitted by the javascript:

render :json => {:success => true, :html => prices_html}, :callback => params[:callback]

With all this, you should be able to do Cross Domain Ajax Request using jQuery.

I love Rails Console. If there is anything wrong with my Rails application, I can simply fire the console, and debug from there. Rails makes the query to db very simple and elegant by providing us the ActiveRecord. However, sometimes you may want to know the underlying raw sql statement being sent to the database to see if there is any problem. Especially your rails app is being quite slow, you may want to check if this could be the problem.


So you know that under development mode, the log would print out the raw sql statements executed. What about Rails Console. By default, if you typed in any code that queries the database, it would simply return the objects back to you. You can do the following in order to show the raw sql statements:


Immediately after you have entered Rails Console, typed in the following code in console:


ActiveRecord::Base.logger = Logger.new(STDOUT)

After that, it should print out the sql queries.

If you expect a database table to grow very large, then you will often create some index on the columns that are used to be searched quite often. E.g. if you have a user table, usually you will create index on the user_id column, as usually you will query the table to check if a user_id exists in database. The benefit of using an index for database table is quite true when the table is large although it has some disadvantage as well, like slower update/new record operation due to the needs to update the index file and it takes up extra disk space as well.

 

If no index exists on a table, a table scan must be performed for each table referenced in a database query. The larger the table, the longer a table scan takes because a table scan requires each table row to be accessed sequentially. Although a table scan might be more efficient for a complex query that requires most of the rows in a table, for a query that returns only some table rows an index scan can access table rows more efficiently.

 

The optimizer chooses an index scan if the index columns are referenced in the SELECT statement and if the optimizer estimates that an index scan will be faster than a table scan. Index files generally are smaller and require less time to read than an entire table, particularly as tables grow larger. In addition, the entire index may not need to be scanned. The predicates that are applied to the index reduce the number of rows to be read from the data pages. – extracts from the IBM website.

 

So when it comes to rails, how do you create index using active record migration?

In order to create database index for a certain table, you might have done the following under active record database migration file before.

def self.up
  create_table :table_names do |t|
     t.string :user_id
     t.index :user_id, :unique => true
  end
end

Although you may be able to find the index function API under rails API page.However, the index won’t be created as expected for you. The right way to create an index is using method add_index after you have created the table .

def self.up
  create_table :table_name do |t|
     t.string :user_id
  end
  add_index :table_name, :user_id, :unique => true
end

index function is only available when doing change_table call. So you can also do the following to create the index:

def self.up
   change_table :table_name do |t|
      t.index :user_id, :unique => true
   end
end

So that is to say an index can be created only when the table is created.
Read the rest of this entry »

Today I ran into a problem when trying to connect to mysql database to download some data using Rails 2. I install mysql using macports. After install mysql, i install mysql gem using the following command:

gem install mysql

This actually installed the latest mysql gem 2.8.1. However, when I run my project in production mode to connect to mysql I get the following error:

uninitialized constant MysqlCompat::MysqlRes

It turns out that mysql 2.8.1 driver seems to have a problem. So to fix this, you should do the following to install mysql 2.7.

export ARCHFLAGS=”-arch i386 -arch x86_64″ ;sudo gem install –no-rdoc –no-ri -v=2.7 mysql — –with-mysql-config=/opt/local/bin/mysql_config5

Do replace the mysql-config to the real configuration path in your os.

For more information do checkout the discussion at StackOverflow