<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7096286173817193675</id><updated>2012-01-01T22:22:13.046-08:00</updated><category term='ruby'/><category term='yui'/><category term='replace_html'/><category term='state machine'/><category term='fsm'/><category term='assert_rjs'/><category term='window.open'/><category term='perl'/><category term='autorevert'/><category term='acts_as_state_machine'/><category term='include'/><category term='location'/><category term='composite'/><category term='find'/><category term='popup'/><category term='css'/><category term='helper'/><category term='deep'/><category term='rails'/><category term='db:create'/><category term='yuirails'/><category term='default'/><category term='eager'/><category term='rake'/><category term='restful atuthentication'/><category term='duplicate entry'/><category term='variable interpolation'/><category term='modalbox'/><category term='resultmap'/><category term='arts'/><category term='ajax'/><category term='migration'/><category term='revert'/><category term='xy'/><category term='query_analyzer'/><category term='loading'/><category term='oracle'/><category term='style'/><category term='rails cookie overflow CookieOverflow session cookiestore'/><category term='link_to'/><category term='optimization'/><category term='habtm'/><category term='index'/><category term='finite'/><category term='IE'/><category term='updater'/><category term='Internet Explorer'/><category term='rbatish'/><category term='request'/><title type='text'>Just Barebones</title><subtitle type='html'>This blog serves as a record of my commentaries about interesting technical tidbits that I come across in my day to day life.

Stuff about RAILS (ROR), Javascript, HTML, CSS, Ruby, Perl, Tcl, *nix, MySQL, Oracle etc etc...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8807731312460635903</id><published>2011-02-06T14:03:00.000-08:00</published><updated>2011-02-06T14:04:59.967-08:00</updated><title type='text'>Benchmarking a system command</title><content type='html'>&lt;pre&gt;&lt;br /&gt;time for((n=0;n&lt;100;n++)); do convert CIMG0022.jpg -rotate 90 CIMG0022_90.jpg; done&lt;br /&gt;&lt;br /&gt;real 0m42.438s&lt;br /&gt;user 0m33.934s&lt;br /&gt;sys 0m8.424s&lt;br /&gt;&lt;br /&gt;Avg run time: ~ 424ms&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8807731312460635903?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8807731312460635903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8807731312460635903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8807731312460635903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8807731312460635903'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2011/02/benchmarking-system-command.html' title='Benchmarking a system command'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-7167583058061147450</id><published>2011-01-31T14:19:00.000-08:00</published><updated>2011-06-09T12:52:19.233-07:00</updated><title type='text'>Getting started with node.js</title><content type='html'>By now everyone has more or less heard of &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt;. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Node.js is an exciting project that takes the super fast V8 javascript engine open sourced by Google and wraps it with an event oriented framework that allows it to process concurrent requests blazingly fast. Event oriented (using one of epoll, kequeue, /dev/poll, select) concurrency model is considered to be much superior to thread based concurrency model - point in case &lt;a href="http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/"&gt;nginx vs Apache&lt;/a&gt; comparison.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Listed below are some resources that I found very useful to get started on node.js.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Main &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; page&lt;br /&gt;Introducuction to node.js. A must read to understand the architectural decisions behind node.js&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/ry/node/wiki/installation"&gt;Installation&lt;/a&gt;&lt;br /&gt;This page contains instructions to install node.js and npm (NodeJS Package Manager).&lt;br /&gt;&lt;meta charset="utf-8"&gt;If you plan to use node-inspector for debugging, install v 0.3.0 or later.&lt;br /&gt;I had trouble installing npm when I installed node in /usr/local. The npm install script complains loudly when invoked as sudo - rightly so as packages can run arbitrary scripts.&lt;br /&gt;Best approach I have found is to install node.js in a local directory as shown in this &lt;a href="https://gist.github.com/741623/f1c71be98c34d377916eeee45b1c9f081577b8bd#file_node_and_npm_in_30_seconds.sh"&gt;gist&lt;/a&gt; (node-and-npm-in-30-seconds.sh) and then install npm.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/isaacs/npm"&gt;Npm&lt;/a&gt;&lt;br /&gt;Npm is NodeJs Package manager. Some links of interest : &lt;a href="http://howtonode.org/introduction-to-npm"&gt;intro to npm&lt;/a&gt;, &lt;a href="https://github.com/isaacs/npm/tree/master/doc"&gt;docs&lt;/a&gt; and a &lt;a href="https://github.com/isaacs/npm/blob/master/doc/faq.md"&gt;faq&lt;/a&gt;. Also here is a list of &lt;a href="http://npm.mape.me/"&gt;npm packages&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/visionmedia/express"&gt;Express&lt;/a&gt;&lt;br /&gt;To simplify setting up a web server using node.js, use the Sinatra inspired Express framework. It is built on top of &lt;a href="https://github.com/senchalabs/connect"&gt;Connect&lt;/a&gt;. I came across an interesting thread regarding a node.js module called &lt;a href="http://groups.google.com/group/nodejs/browse_thread/thread/479e1e5de272931d"&gt;Nitrode&lt;/a&gt; which points out high memory usage of Connect when streaming large files.&lt;br /&gt;You can generate a skeleton app using  &lt;strong&gt;express &amp;lt;appname&amp;gt;&lt;/strong&gt;&lt;br /&gt;Very useful -  &lt;a href="http://dailyjs.com/2010/11/08/node-tutorial-2/"&gt;details&lt;/a&gt; on the skeleton generated using the command above (scroll down half-way)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;node-inspector&lt;br /&gt;&lt;b&gt;Needs node.js &gt; 0.3.0 &lt;/b&gt;&lt;br /&gt;Read up on node-inspector at https://github.com/dannycoates/node-inspector and https://github.com/past/node-inspector&lt;br /&gt;npm install node-inspector&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-7167583058061147450?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/7167583058061147450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=7167583058061147450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7167583058061147450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7167583058061147450'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2011/01/getting-started-with-nodejs.html' title='Getting started with node.js'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-4313496771708187952</id><published>2009-06-22T22:58:00.000-07:00</published><updated>2009-06-22T23:09:25.818-07:00</updated><title type='text'>Thread programming ref reshers - ruby style</title><content type='html'>A quick link pointer - differences b/w &lt;a href="http://www.ruby-forum.com/topic/49879"&gt;ruby mutex and monitors&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some quick tips:&lt;br /&gt;Monitors are re-entrant - meaning you can nest calls to methods that synchronize access to some data&lt;br /&gt;Mutex is not re-entrant&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-4313496771708187952?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/4313496771708187952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=4313496771708187952' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4313496771708187952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4313496771708187952'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2009/06/thread-programming-ref-reshers-ruby.html' title='Thread programming ref reshers - ruby style'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8416595073544605266</id><published>2009-05-26T00:41:00.000-07:00</published><updated>2009-05-26T00:45:36.457-07:00</updated><title type='text'>Ruby blocks  -  explicit vs implicit arguments</title><content type='html'>I wanted to pass an implicit block argument to a call to super. Looks like the most efficient way is to use &lt;br /&gt;&lt;br /&gt;def on_ready&lt;br /&gt;   unless paused?&lt;br /&gt;     super { yield }&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;-----------------------&lt;br /&gt;&lt;br /&gt;From http://www.ruby-forum.com/topic/71221&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;require 'benchmark'&lt;br /&gt;&lt;br /&gt;def outer11(&amp;bl)&lt;br /&gt;  inner1(&amp;bl)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def outer12(&amp;bl)&lt;br /&gt;  inner2(&amp;bl)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def outer21&lt;br /&gt;  inner1 {yield}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;def outer22&lt;br /&gt;  inner2 {yield}&lt;br /&gt;end&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;def inner1(&amp;bl)&lt;br /&gt;  bl.call&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def inner2&lt;br /&gt;  yield&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;n = 100000&lt;br /&gt;&lt;br /&gt;Benchmark.bmbm(10) do |rpt|&lt;br /&gt;  rpt.report("outer11") do&lt;br /&gt;    n.times {outer11{}}&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  rpt.report("outer12") do&lt;br /&gt;    n.times {outer12{}}&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  rpt.report("outer21") do&lt;br /&gt;    n.times {outer21{}}&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  rpt.report("outer22") do&lt;br /&gt;    n.times {outer22{}}&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;__END__&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;Rehearsal ---------------------------------------------&lt;br /&gt;outer11     0.890000   0.010000   0.900000 (  0.894500)&lt;br /&gt;outer12     0.370000   0.000000   0.370000 (  0.364880)&lt;br /&gt;outer21     0.770000   0.000000   0.770000 (  0.776638)&lt;br /&gt;outer22     0.170000   0.000000   0.170000 (  0.163393)&lt;br /&gt;------------------------------------ total: 2.210000sec&lt;br /&gt;&lt;br /&gt;                user     system      total        real&lt;br /&gt;outer11     0.490000   0.000000   0.490000 (  0.491969)&lt;br /&gt;outer12     0.400000   0.000000   0.400000 (  0.396264)&lt;br /&gt;outer21     0.760000   0.000000   0.760000 (  0.764508)&lt;br /&gt;outer22     0.160000   0.000000   0.160000 (  0.161982)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8416595073544605266?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8416595073544605266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8416595073544605266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8416595073544605266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8416595073544605266'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2009/05/ruby-blocks-explicit-vs-implicit.html' title='Ruby blocks  -  explicit vs implicit arguments'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5430914800621354743</id><published>2009-03-22T23:53:00.001-07:00</published><updated>2009-03-23T00:01:31.810-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails cookie overflow CookieOverflow session cookiestore'/><title type='text'>CookierStore::CookieOverflow</title><content type='html'>&lt;pre&gt;&lt;br /&gt;/!\ FAILSAFE /!\  Sun Mar 22 23:51:44 -0700 2009&lt;br /&gt;  Status: 500 Internal Server Error&lt;br /&gt;  ActionController::Session::CookieStore::CookieOverflow&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This error is typically due to the user trying to store &gt; 4K of data in the session.&lt;br /&gt;&lt;br /&gt;Another source of error is if you try to store $! in flash[:error]&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;begin&lt;br /&gt;  ....&lt;br /&gt;rescue &lt;br /&gt;  flash[:error] = $!&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This tries to store the ruby exception object in the flash (which in turn is stored in the cookie) and you will start getting the cookie overflow errors.&lt;br /&gt;&lt;br /&gt;The solution is simple&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;begin&lt;br /&gt;  ....&lt;br /&gt;rescue &lt;br /&gt;  flash[:error] = $!.to_s&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;-&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5430914800621354743?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5430914800621354743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5430914800621354743' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5430914800621354743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5430914800621354743'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2009/03/cookierstorecookieoverflow.html' title='CookierStore::CookieOverflow'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5759315549590537854</id><published>2008-11-04T14:29:00.000-08:00</published><updated>2008-11-04T14:39:51.577-08:00</updated><title type='text'>ORA-12516: TNS:listener could not find available handler with matching protocol stack</title><content type='html'>We use Oracle Database 10g Express Edition Release 10.2.0.1.0 for our RoR development and were hitting the TNS:listener error all the time. This made concurrent development a real pain and we couldn't leave staging servers and sqldeveloper sessions up.&lt;br /&gt;&lt;br /&gt;Google searches turned up really scant information - mainly advices to increase the PROECESSES limit. I am not a DBA, so wasn't sure what needed to be done. &lt;br /&gt;In any case, the following solution worked like a charm and I hope others who have this issue find this post useful.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;source /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.csh&lt;br /&gt;setenv ORACLE_SID XE&lt;br /&gt;&lt;br /&gt;And then execute the following steps to increase the number processes and sessions:&lt;br /&gt;1) Connect to the database using the sys or system user:&lt;br /&gt;sqlplus SYSTEM/&amp;lt;syspwd&amp;gt;@//&amp;lt;dbhost&amp;gt;/xe&lt;br /&gt;2) To confirm the PROCESSES and SESSIONS values, run the following script:&lt;br /&gt; sql&gt; col name format A30&lt;br /&gt; Sql&gt; col value format A30&lt;br /&gt; sql&gt; select name, value from v$parameter where name in ('processes','sessions');&lt;br /&gt;3) SQL&gt; alter system set processes=300 scope=spfile;&lt;br /&gt;4) SQL&gt; alter system set sessions=300 scope=spfile;&lt;br /&gt;5) Bounce the database to reflect the changes&lt;br /&gt;6) To confirm new values run the script (2).&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5759315549590537854?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5759315549590537854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5759315549590537854' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5759315549590537854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5759315549590537854'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/11/ora-12516-tnslistener-could-not-find.html' title='ORA-12516: TNS:listener could not find available handler with matching protocol stack'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-933806025186366135</id><published>2008-10-09T11:04:00.000-07:00</published><updated>2008-10-09T15:29:51.431-07:00</updated><title type='text'>Building Custom Deployment directories using sprinkle</title><content type='html'>At work we deploy multiple RoR applications on each server. Managing the environments for all these applications is a huge headache. We have applications in production using Rails 1.2.5 all the way till Rails 2.1.1.  In addition to rails, other gems need updates routinely as well.  This breaks applications that have been running smoothly for the past year or so.&lt;br /&gt;Further, new IT policy changes have taken away developer's sudo access on these servers, which makes developing cumbersome and difficult - having to go through IT for every environment update request.&lt;br /&gt;&lt;br /&gt;So I set upon the task of developing an easy way to deploy each application in its own environment.&lt;br /&gt;Following are the goals I wanted to achieve:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Each application runs in its own deployment environment. By environment I mean a complete directory structure that has its own ruby and gem installation, along with any additional software such as database, web server, Imagemagick, reverse proxy etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The environment should be easy to duplicate for staging and development, thus keeping the production environment isolated until QA is done and the application is ready to be deployed in production&lt;/li&gt;&lt;li&gt;The environment should be easy to build - fire off a script and go get a coffee while the environment is being built and configured.&lt;/li&gt;&lt;/ul&gt;I gave &lt;a href="http://www.fiveruns.com/products/install"&gt;Fiveruns install&lt;/a&gt; a try. It is a great product, but the stack is not extensible - I cannot add additional software components to the install process.&lt;br /&gt;&lt;br /&gt;I came upon Marcus Crafter's  &lt;a href="http://redartisan.com/2008/5/27/sprinkle-intro"&gt;sprinkle&lt;/a&gt; which allows easy provisioning of new VPS systems. It is an awesome piece of code that makes setting up new systems a breeze.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Sprinkle is a new prototype tool that you can use to provision your servers/slices. Its declarative policy/state based approach for specifying how a remote system should be provisioned with intelligent logic to support dependencies, multiple installer types and remote installation is really compelling.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The ruby based DSL used to describe the provisioning setup is easy to understand and maintain.&lt;br /&gt;&lt;br /&gt;However, sprinkle in its current form provisioned the entire system to a specific deployment environment - not what I had in mind.&lt;br /&gt;So I created a &lt;a href="http://github.com/cpatil/sprinkle/tree/master"&gt;fork&lt;/a&gt; of the sprinkle codebase on github and added the capability to build local deployment directories to sprinkle.&lt;br /&gt;Here is a log of the functionality I added:&lt;br /&gt;             &lt;div class="message"&gt;&lt;ol&gt;&lt;li&gt;bin/sprinkle - updated to accept -d &lt;deploy_dir&gt; option and create a environment&lt;span style="font-family:monospace;"&gt; &lt;/span&gt;source file at the end&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;/deploy_dir&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;sprinkle.gemspec - added actors/local.rb which was missing&lt;/li&gt;&lt;li&gt;lib/sprinkle/actors/local.rb - updated to set env vars before calling the system command (sets PATH and LD_LIB to the deploy dir), also raises an exeception if a command fails&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;lib/sprinkle/installers/gem.rb - by default doesn't build ri and rdoc anymore - need to specify build_docs as a gem option&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;lib/sprinkle/installers/source.rb - custom_install is now an array of commands, added custom_stage &lt;stage&gt;, cmd to override default stages, source now accepts a path as a valid option to copy the archive from.&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;/stage&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;lib/sprinkle/verifiers/ruby.rb - removed sudo while verifying a gem&lt;/li&gt;&lt;li&gt;Added has_successful_execution verifier to verify installations&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;To get started with this new functionality:&lt;br /&gt;&lt;br /&gt;&lt;div class="commands"&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install the sprinkle gem.&lt;br /&gt;- git clone                                          &lt;a href="git://github.com/cpatil/sprinkle.git" class="git_url_facebox" rel="#git-clone"&gt;git://github.com/cpatil/sprinkle.git&lt;/a&gt;&lt;br /&gt;- cd sprinkle&lt;br /&gt;- gem build sprinkle.gemspec&lt;br /&gt;- gem install sprinkle.gemspec&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a sprinkle recipe (&lt;a href="http://cpatil.googlepages.com/build_deployment_env.rb"&gt;download&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Run sprinkle and go get a coffee&lt;br /&gt;- sprinkle -c - v -d deploy_dir -s build_deployment_env.rb&lt;/li&gt;&lt;li&gt;Source the env.&lt;br /&gt;- source deploy_dir/source_env.tcsh&lt;/li&gt;&lt;li&gt;Test the paths&lt;br /&gt;- which ruby&lt;br /&gt;- which gem&lt;br /&gt;- gem list&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Now cd to your rails application dir and start up the server - Voila - custom a la carte deployment environments :)&lt;br /&gt;&lt;br /&gt;Njoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-933806025186366135?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/933806025186366135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=933806025186366135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/933806025186366135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/933806025186366135'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/10/building-custom-deployment-directories.html' title='Building Custom Deployment directories using sprinkle'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-712203116645558812</id><published>2008-05-25T10:16:00.000-07:00</published><updated>2008-05-25T10:22:01.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful atuthentication'/><category scheme='http://www.blogger.com/atom/ns#' term='db:create'/><category scheme='http://www.blogger.com/atom/ns#' term='rake'/><title type='text'>Rails 2.0.2, restful authentication and db:create</title><content type='html'>Rails 2.0.2, restful authentication and rake db:create don't seem to play nice :(&lt;br /&gt;&lt;br /&gt;rake db:create gives me&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;rake aborted!&lt;br /&gt;Unknown database 'xxxx_devel'&lt;br /&gt;&lt;br /&gt;(See full trace by running task with --trace)&lt;/blockquote&gt;&lt;br /&gt;Using rake --trace db:create pointed me to the following line in config/environment.rb:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;config.active_record.observers = :user_observer&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;which I had added as part of configuration setup for restful_authentication.&lt;br /&gt;&lt;br /&gt;I commented out this line and rake db:create ran fine. I will investigate more later, but this got me going for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-712203116645558812?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/712203116645558812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=712203116645558812' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/712203116645558812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/712203116645558812'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/05/rails-202-restful-authentication-and.html' title='Rails 2.0.2, restful authentication and db:create'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5263204373866947913</id><published>2008-05-19T12:42:00.000-07:00</published><updated>2008-05-19T12:52:43.596-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resultmap'/><category scheme='http://www.blogger.com/atom/ns#' term='default'/><category scheme='http://www.blogger.com/atom/ns#' term='rbatish'/><title type='text'>rbatis patch for custom (non default) resultmaps</title><content type='html'>I had to use the following patch to make custom resultmaps (i.e. non :default resultmaps) work with rbatis:&lt;br /&gt;&lt;br /&gt;vendor/plugins/rbatis/lib/rbatis.rb (line 406)&lt;br /&gt;&lt;blockquote&gt;     def statement(statement_type, name = statement_type, params = {}, &amp;amp;proc)&lt;br /&gt;  ...&lt;br /&gt;  statement.connection_provider = self&lt;br /&gt;         if statement.respond_to?(:resultmap=) &amp;amp;&amp;amp; statement.resultmap.nil?&lt;br /&gt;             statement.resultmap = resultmaps[:default]&lt;br /&gt;         else&lt;br /&gt;             statement.resultmap = resultmaps[statement.resultmap]&lt;br /&gt;          end&lt;br /&gt;         statement.validate&lt;br /&gt; ...&lt;br /&gt;end&lt;/blockquote&gt;rbatis is pretty slick, especially when you have to work with legacy databases and schemas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5263204373866947913?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5263204373866947913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5263204373866947913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5263204373866947913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5263204373866947913'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/05/rbatis-patch-for-custom-non-default.html' title='rbatis patch for custom (non default) resultmaps'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8994258907593124460</id><published>2008-05-13T09:06:00.000-07:00</published><updated>2008-05-16T07:35:39.094-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='query_analyzer'/><category scheme='http://www.blogger.com/atom/ns#' term='index'/><category scheme='http://www.blogger.com/atom/ns#' term='composite'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle Query optimization</title><content type='html'>We are working on a RoR application that needs to crunch data across multiple tables (&gt; 7 million records)  from a huge Oracle database. The sql queries were initially taking a long time, upto 5 minutes for some queries.&lt;br /&gt;Following are some links and tips to optimize the sql queries - specific to Oracle.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I added the following snippet to the environment.rb which gives me some stats for the queries:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;# only run this code in development&lt;br /&gt;if ENV["RAILS_ENV"] == "development"&lt;br /&gt;&lt;br /&gt;# modify MysqlAdapter to track transfer stats&lt;br /&gt;class ActiveRecord::ConnectionAdapters::OracleAdapter&lt;br /&gt;  @@stats_queries = @@stats_bytes = @@stats_rows = 0&lt;br /&gt;&lt;br /&gt;  def self.get_stats&lt;br /&gt;    { :queries =&gt; @@stats_queries,&lt;br /&gt;      :rows =&gt; @@stats_rows,&lt;br /&gt;      :bytes =&gt; @@stats_bytes }&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.reset_stats&lt;br /&gt;    @@stats_queries = @@stats_bytes = @@stats_rows = 0&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def select_with_stats(sql, name)&lt;br /&gt;    bytes = 0&lt;br /&gt;    rows = select_old(sql, name)&lt;br /&gt;    rows.each do |row|&lt;br /&gt;      row.each do |key, value|&lt;br /&gt;        bytes += key.length&lt;br /&gt;        bytes += value.length if value &amp;amp;&amp;amp; value.respond_to?('length')&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    @@stats_queries += 1&lt;br /&gt;    @@stats_rows += rows.length&lt;br /&gt;    @@stats_bytes += bytes&lt;br /&gt;    @logger.info sprintf("%d rows, %.1fk", rows.length, bytes.to_f / 1024)&lt;br /&gt;    rows&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  alias :select_old :select&lt;br /&gt;  alias :select :select_with_stats&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# modify ActionController to reset/print stats for each request&lt;br /&gt;class ActionController::Base&lt;br /&gt;  def perform_action_reset&lt;br /&gt;    ActiveRecord::ConnectionAdapters::OracleAdapter::reset_stats&lt;br /&gt;    perform_action_old&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  alias :perform_action_old :perform_action&lt;br /&gt;  alias :perform_action :perform_action_reset&lt;br /&gt;&lt;br /&gt;  def active_record_runtime(runtime)&lt;br /&gt;    stats = ActiveRecord::ConnectionAdapters::OracleAdapter::get_stats&lt;br /&gt;    "#{super} #{sprintf("%.1fk", stats[:bytes].to_f / 1024)}"&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# trim blob logging&lt;br /&gt;#class ActiveRecord::ConnectionAdapters::OracleAdapter&lt;br /&gt;#def format_log_entry(message, dump = nil)&lt;br /&gt;  #if dump&lt;br /&gt;    #dump = dump.gsub(/x.([^.]+)./) do |blob|&lt;br /&gt;      #(blob.length &gt; 32) ? "x.#{$1[0,32]}. (#{blob.length} bytes)." : $0&lt;br /&gt;    #end&lt;br /&gt;  #end&lt;br /&gt;  #super&lt;br /&gt;#end&lt;br /&gt;#end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Check out this &lt;a href="http://www.oracle.com/technology/pub/articles/mearelli-optimizing-oracle-rails.html"&gt;link &lt;/a&gt;on Oracle.com and download the Oracle version of &lt;a href="http://www.spazidigitali.com/wp-content/uploads/2006/12/query_analyzer.zip"&gt;query_analyzer&lt;/a&gt;. This plugin automatically runs an&lt;a href="http://www.stanford.edu/dept/itss/docs/oracle/9i/server.920/a96533/ex_plan.htm#19259"&gt; explain plan&lt;/a&gt; query for the select query.&lt;br /&gt;&lt;blockquote&gt;Analyzing&lt;br /&gt;plan_table_output&lt;br /&gt; --------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt; --------------------------------------------------------------------&lt;br /&gt; | Id  | Operation                           |  Name  | Rows  | Bytes | Cost  |&lt;br /&gt; --------------------------------------------------------------------&lt;br /&gt; |   0 | SELECT STATEMENT    |              |     1   |    31   |  8598 |&lt;br /&gt; |   1 |  SORT UNIQUE                |              |     1    |    31   |  8598 |&lt;br /&gt; |   2 |   TABLE ACCESS FULL   | XXX   |   128 |  3968 |  8583 |&lt;br /&gt; --------------------------------------------------------------------&lt;/blockquote&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;First level of optimization&lt;/span&gt;: the &lt;a href="http://www.stanford.edu/dept/itss/docs/oracle/9i/server.920/a96533/optimops.htm#75195"&gt;output of the explain plan&lt;/a&gt; shows you which tables columns in the WHERE clause  cause a FULL table access. These columns are targets for optimizations by dropping indexes on them. This will result in a explain plan output as shown below. Note the INDEX RANGE SCAN bit.&lt;br /&gt;&lt;blockquote&gt;   ----------------------------------------------------------------------------&lt;br /&gt; | Id  | Operation                                              |  Name                   | Rows  | Bytes | Cost  |&lt;br /&gt; ----------------------------------------------------------------------------&lt;br /&gt; |   0 | SELECT STATEMENT                        |                                |    25 |   675 |   332 |&lt;br /&gt; |   1 |  TABLE ACCESS BY INDEX ROWID| XX_XXXXX         |    25 |   675 |   332 |&lt;br /&gt; |   2 |   INDEX RANGE SCAN                       | XX_X_INDEX1  |   430 |       |     4 |&lt;br /&gt; ----------------------------------------------------------------------------&lt;br /&gt;&lt;/blockquote&gt;However, being too aggressive in creating indexes is not recommended. An index is essentially a seperate file on the filesystem and every time the table data is altered, each of the index files need to be updated.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Second level of optimization&lt;/span&gt;: Read this &lt;a href="http://www.akadia.com/services/ora_index_selectivity.html"&gt;link &lt;/a&gt;to understand Index selectivity. Here are the steps I took to gather statistics and compute selectivity:&lt;br /&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Download and install SQL Developer from oracle.com and connect to the database.&lt;/li&gt;&lt;li&gt;Right click on Table -&gt; Statistics -&gt; Gather statistics&lt;br /&gt;Alternately, you can run the following query:&lt;br /&gt;analyze table XXXX compute statistics;&lt;br /&gt;select column_name, num_distinct from user_tab_columns where table_name='XXXXX'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Note the number of distinct values of the data in the column you are interested in. Alternately run a sql query such as&lt;br /&gt;select count(distinct &lt;columnname&gt;) from XXXXX&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/columnname&gt;&lt;/li&gt;&lt;li&gt;Run a sql query to get number of records in the table:&lt;br /&gt;select count(*) from XXXXX&lt;/li&gt;&lt;li&gt;Index selectivity = Distinct Column values / Num rows in table&lt;/li&gt;&lt;li&gt;A larger value for Index selectivity is good. This means there are fewer rows corresponding to the column's each distinct value.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;In my case, due to a large number of records in the table and the num distinct values of the columns being small, the index selectivity was less than 0.01. So even after adding indexs on the columns in the WHERE clause, the query was slow. In fact it made loading data into the database slower.&lt;br /&gt;However if the query is returning only the indexed column's data in the SELECT clause, the data can be returned from the index file directly (the table data is not referred) and that indeed may result in a faster query.&lt;br /&gt;Another option is to consider a &lt;a href="http://www.oracle.com/technology/pub/articles/sharma_indexes.html"&gt;Bitmap index&lt;/a&gt; instead of a B-Tree index. Bitmap indexes are useful when the column to be indexed has low cardinality, e.g. gender or marital status. Bitmap indexes work well with Data warehousing kind of apps which B-Tree indexes (typical) are more common with OLTP systems. So consider the &lt;a href="http://www.akadia.com/services/ora_bitmapped_index.html"&gt;Bitmap index characteristics&lt;/a&gt; and impact on your application carefully before deciding on using Bitmap indexes. Especially the fact that inserting data into tables with bitmap indexes is a lot slower than tables with B-Tree indexes.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Third level of optimization&lt;/span&gt;: Composite indexes. Sometimes indexes with lower selectivity can be combined into a composite index to create an overall index with a higher selectivity. Oracle also supports &lt;a href="http://www.praetoriate.com/oracle_tips_skip_scan.htm"&gt;Index Skip scan&lt;/a&gt; which allows a composite index to be used even when all the columns specified in the composite index are not present in the SQL WHERE clause.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Note that using LIKE '%xxx'   and other terms in the WHERE clause can cause FULL Table scans. However LIKE 'xxx%' can potentially use an index. There are several options as listed &lt;a href="http://www.orafaq.com/node/1918"&gt;here&lt;/a&gt; and &lt;a href="http://jeffkemponoracle.blogspot.com/2008/01/like-with-wildcard-at-start-can-use.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Links:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/pls/db92/db92.docindex"&gt;Oracle 9i Books portal&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.stanford.edu/dept/itss/docs/oracle/9i/appdev.920/a96590/adg06idx.htm"&gt;Selecting an Index strategy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.akadia.com/services/ora_index_selectivity.html"&gt;Index Selectivity&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/technology/pub/articles/mearelli-optimizing-oracle-rails.html"&gt;Tips for optimizing Rails on Oracle&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a aiotarget="false" aiotitle="Query Analyzer for Oracle" href="http://www.spazidigitali.com/wp-content/uploads/2006/12/query_analyzer.zip"&gt;Query Analyzer for Oracle&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.stanford.edu/dept/itss/docs/oracle/9i/server.920/a96533/ex_plan.htm#19259"&gt;Using EXPLAIN PLAN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.stanford.edu/dept/itss/docs/oracle/9i/server.920/a96533/optimops.htm#75195"&gt;Steps in the EXPLAIN PLAN output&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle-base.com/articles/8i/CostBasedOptimizerAndDatabaseStatistics.php"&gt;Computing Table and Database statistics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/technology/pub/articles/sharma_indexes.html"&gt;Bitmap Index vs B-Tree index&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.akadia.com/services/ora_bitmapped_index.html"&gt;Secrets of Bitmap indexes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.orafaq.com/node/1918"&gt;Tuning a LIKE clause&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jeffkemponoracle.blogspot.com/2008/01/like-with-wildcard-at-start-can-use.html"&gt;LIKE with % at START&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 class="Title"&gt;&lt;a href="http://www.orafaq.com/node/1918"&gt;&lt;span&gt;&lt;span style="color: rgb(51, 0, 153);font-family:Arial,Helvetica,sans-serif;" &gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span style="color: rgb(51, 0, 153);font-family:Arial,Helvetica,sans-serif;" &gt;&lt;a name="ADFNS005"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8994258907593124460?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8994258907593124460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8994258907593124460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8994258907593124460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8994258907593124460'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/05/oracle-optimization.html' title='Oracle Query optimization'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3259303331288481915</id><published>2008-01-18T22:30:00.001-08:00</published><updated>2008-02-25T01:58:26.491-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='yuirails'/><category scheme='http://www.blogger.com/atom/ns#' term='yui'/><category scheme='http://www.blogger.com/atom/ns#' term='updater'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='request'/><title type='text'>Announcing YUIRails</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;Update 2/24/08 - I have uploaded new versions of &lt;/span&gt;&lt;a style="color: rgb(255, 0, 0);" href="http://cpatil.googlepages.com/yuirails.js"&gt;yuirails.js&lt;/a&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; and&lt;/span&gt;&lt;a style="color: rgb(255, 0, 0);" href="http://cpatil.googlepages.com/yuirails-min.js.2.24.08"&gt; yuirails-min.js&lt;/a&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;The new version adds file upload capability (YUI + YuiRails + attachment_fu) and fixes a few misc bugs. The file upload capability works with single as well as multiple file uploads (ajax). I will be posting on this in coming weeks. Let me know if there is interest and I will try to put it up sooner. The &lt;a href="http://loop6.com:3000/"&gt;demo &lt;/a&gt;with the new js files is &lt;a href="http://cpatil.googlepages.com/yuirails.tgz"&gt;here&lt;/a&gt; and is otherwise unchanged.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I am using YUI with Rails at work to develop a complex web application using the treeview, panel, connection, and various other widgets. I used to miss being able to use link_to_remote and remote_form_for without having to include prototype.js (which at the latest version is about 124KB.&lt;br /&gt;So over the Christmas break, I sat down and coded up YUIRails. The intent of this library is to provide a thin layer of logic that glues RJS - PrototypeHelper with YUI connection manager. In its present form, it provides partial support for RJS Prototypehelper, limited to Element methods and Ajax.Request and Ajax.Updater. No support is provided for Scriptaculous effects.&lt;br /&gt;&lt;br /&gt;To use this library, simply drop it in public/javascripts. In its uncompressed form it is at 18K, but a minimized version is only 6K. If there is enough interest, I will look into making the code tighter.&lt;br /&gt;&lt;br /&gt;Following are a few restrictions in the usage:&lt;br /&gt;a) I have stayed away from extending Dom elements with Element.methods. As a result you can't call $('foo').hide(); Rather you will have to use Element.hide('foo');&lt;br /&gt;b) Following Element methods are supported:&lt;br /&gt;- visible&lt;br /&gt;- toggle&lt;br /&gt;- hide&lt;br /&gt;- show&lt;br /&gt;- remove&lt;br /&gt;- update&lt;br /&gt;- replace&lt;br /&gt;&lt;br /&gt;As a demo, a simple rails application is included in the distribution. You will need to create a MYSQL database test_yuirails_development owned by yuirails/testing&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create database test_yuirails_development;&lt;br /&gt;GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX ON test_yuirails_development.* TO 'yuirails'@'localhost' IDENTIFIED BY 'testing';&lt;br /&gt;&lt;br /&gt;and then&lt;br /&gt;&lt;br /&gt;rake db:migrate&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/demo.tgz"&gt;demo.tgz&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/yuirails.js"&gt;yuirails.js&lt;/a&gt; - 18K&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/yuirails-min.js"&gt;yuirails-min.js&lt;/a&gt; - 6.5K&lt;br /&gt;&lt;br /&gt;I just setup the demo on a server. &lt;a href="http://loop6.com:3000/"&gt;Check&lt;/a&gt; it out.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3259303331288481915?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3259303331288481915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3259303331288481915' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3259303331288481915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3259303331288481915'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2008/01/announcing-yuirails.html' title='Announcing YUIRails'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3342401032097190899</id><published>2007-12-25T14:25:00.000-08:00</published><updated>2007-12-25T23:12:18.979-08:00</updated><title type='text'>Quick ActionMailer tips</title><content type='html'>To include your helpers (defined in application_helper.rb), do a &lt;br /&gt;helper :application&lt;br /&gt;in the mailer class defined in app/models.&lt;br /&gt;&lt;br /&gt;To be able to use url_for and restful route helpers in the ActionMailer model, do an include ActionController::UrlWriter and set default_url_options[:host] to your host.&lt;br /&gt;If you want to use html_escape (h) in html email templates, feel free. html_escape is defined in ERB, so it is already available.&lt;br /&gt;&lt;br /&gt;To add a Return-Path header&lt;br /&gt;http://www.spacebabies.nl/2007/02/16/return-path-in-rails-actionmailer/&lt;br /&gt;&lt;br /&gt;To disble ActionMailer from printing in the production log,&lt;br /&gt;config/environments/production.rb&lt;br /&gt;ActionMailer::Base.logger = nil&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I want to send an email to multiple users, but not show other email addresses in the To line. For now I am simply looping over the emails and sending a seperate email &lt;br /&gt;by calling Mailer.deliver_ method for each email addresses. I can easily imagine this to be a configuration option to ActionMailer so it can do this looping itself.&lt;br /&gt;&lt;br /&gt;This is a good &lt;a href="http://www.igvita.com/blog/2007/07/21/sendmail-spam-filter-tricks-in-rails/"&gt;read&lt;/a&gt; on the topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3342401032097190899?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3342401032097190899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3342401032097190899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3342401032097190899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3342401032097190899'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/quick-actionmailer-tips.html' title='Quick ActionMailer tips'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5823997903401473168</id><published>2007-12-17T21:56:00.000-08:00</published><updated>2007-12-17T22:09:49.365-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='migration'/><category scheme='http://www.blogger.com/atom/ns#' term='revert'/><category scheme='http://www.blogger.com/atom/ns#' term='autorevert'/><title type='text'>Auto reverting Migrations</title><content type='html'>I often end up writing some code in self.up that craps out and it is painful to reverse any database changes that may have been committed. I often resort to revert to an earlier version, but that is an extra step I would rather not have to do.&lt;br /&gt;&lt;br /&gt;I make sure all the extra code is located after any database changes I want to make and then wrap the whole shebang in a begin-rescue block:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class FixCategoriesOrder &lt; ActiveRecord::Migration&lt;br /&gt;  def self.up&lt;br /&gt;    begin&lt;br /&gt;      add_column :categories, :sort_order, :integer&lt;br /&gt;      # ... other database changes&lt;br /&gt;&lt;br /&gt;      # Code &lt;br /&gt;      [["Immunology", 1],&lt;br /&gt;        ["Biochemistry", 2],&lt;br /&gt;        ["Biotechnology", 3],&lt;br /&gt;        ["Cell Biology", 4],&lt;br /&gt;        ["Genomics", 5],&lt;br /&gt;        ["Plant Biology", 6],&lt;br /&gt;        ["Developmental Biology", 7],&lt;br /&gt;        ["Ecology", 8],&lt;br /&gt;        ["Other", 100]].each do |ar|&lt;br /&gt;        puts "Processing #{ar[0]} - #{ar[1]}"&lt;br /&gt;        Category.find_by_name(ar[0]).update_attribute(:sort_order, ar[1])&lt;br /&gt;      end&lt;br /&gt;    rescue&lt;br /&gt;      self.down&lt;br /&gt;      raise $!&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.down&lt;br /&gt;    remove_column :categories, :sort_order&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Njoy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5823997903401473168?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5823997903401473168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5823997903401473168' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5823997903401473168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5823997903401473168'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/auto-reverting-migrations.html' title='Auto reverting Migrations'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6317258283792219959</id><published>2007-12-17T19:12:00.000-08:00</published><updated>2007-12-17T19:17:08.829-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='popup'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='window.open'/><category scheme='http://www.blogger.com/atom/ns#' term='link_to'/><title type='text'>link_to helper, popup option  and  IE window.open</title><content type='html'>Ah, the amount of time spent on this could have really been well spent elsewhere! &lt;br /&gt;&lt;br /&gt;If you trying to use link_to as below:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  link_to "View Image", { :action =&gt; "view" }, :popup =&gt; ['new_window_name', 'height=300,width=600']&lt;br /&gt;  # =&gt; &lt;a href="/testing/view/" onclick="window.open(this.href,'new_window_name','height=300,width=600');return false;"&gt;View Image&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Be very careful when you specify 'new_window_name'.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;It shouldn't have any embedded spaces in the string&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Else IE will barf and throw a runtime exception! Firefox works fine though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6317258283792219959?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6317258283792219959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6317258283792219959' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6317258283792219959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6317258283792219959'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/linkto-helper-popup-option-and-ie.html' title='link_to helper, popup option  and  IE window.open'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-4964463883972144627</id><published>2007-12-16T13:32:00.001-08:00</published><updated>2007-12-16T13:37:56.211-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='habtm'/><category scheme='http://www.blogger.com/atom/ns#' term='duplicate entry'/><title type='text'>has_and_belongs_to_many (HABTM) and MySQL Duplicate entry  error</title><content type='html'>A quick post:&lt;br /&gt;If you use migrations to create a join table for a HABTM relationship, you should tell rails not to automatically add an id column in the migration (Agile book - 271).&lt;br /&gt;Otherwise you will get a &lt;br /&gt;&lt;blockquote&gt;Mysql::Error: Duplicate entry '#' for key #&lt;br /&gt;&lt;/blockquote&gt;error.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create_table :authors_books, :id =&gt; false do |t|&lt;br /&gt;   t.column :author_id, :integer, :null =&gt; false&lt;br /&gt;   t.column :book_id,   :integer, :null =&gt; false&lt;br /&gt;end &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-4964463883972144627?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/4964463883972144627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=4964463883972144627' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4964463883972144627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4964463883972144627'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/hasandbelongstomany-habtm-and-mysql.html' title='has_and_belongs_to_many (HABTM) and MySQL Duplicate entry  error'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8058514812971767206</id><published>2007-12-11T16:34:00.000-08:00</published><updated>2007-12-11T18:26:46.856-08:00</updated><title type='text'>Installing Oracle 10g Express Edition on Linux White box - AMD 64  (x86_64)</title><content type='html'>I had difficulty installing Oracle 10g express edition server on 64 bit White box linux earlier. So I had installed it on my WIndows XP box to use it with my RoR application.&lt;br /&gt;&lt;br /&gt;Today my windows box crashed and I hunkered down and figured out how to install Oracle on my linux box.  There are a couple of tricky steps that could trip you up.  I am documenting the steps here hoping it will help someone out.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download Oracle 10g Express Edition rpm from the Oracle website - oracle-xe-10.2.0.1-1.0.i386.rpm (221136869 bytes)&lt;/li&gt;&lt;li&gt;** Don't use sudo to install the rpm. Log in as root and then run&lt;br /&gt;&lt;span style="font-style: italic;"&gt;rpm -Uvh oracle-xe-10.2.0.1-1.0.i386.rpm&lt;/span&gt;&lt;br /&gt;Otherwise you will get the following error when you try to run sqlplus to connect to the db.&lt;br /&gt;&lt;pre&gt;ORA-01034: ORACLE not available&lt;br /&gt;ORA-27101: shared memory realm does not exist&lt;br /&gt;Linux Error: 2: No such file or directory&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Also, the web server component of the Oracle server never starts if you use sudo to install the rpm. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run configure to configure the server.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;** If you get&lt;br /&gt;&lt;pre&gt;oracleXE: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory&lt;br /&gt;&lt;/pre&gt;then you need to install the 32 bit version of libaio library&lt;br /&gt;&lt;pre&gt;sudo rpm -Uvh http://fedora.osmirror.nl/core/development/i386/os/Fedora/RPMS/libaio-0.3.106-2.2.i386.rpm&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Source the env before you run sqlplus&lt;br /&gt;&lt;pre&gt;source /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.csh&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Look in  /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/network/log/listener.log if the listener or the web server (127.0.0.1:8080/apex) doesn't start. It may contain possible reasons.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Since the web server is bound to 127.0.0.1, to connect to the oracle web server from a remote machine, you will need to use putty (or similar) to create a ssh tunnel.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8058514812971767206?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8058514812971767206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8058514812971767206' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8058514812971767206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8058514812971767206'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/installing-oracle-10g-express-edition.html' title='Installing Oracle 10g Express Edition on Linux White box - AMD 64  (x86_64)'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-2786918237139850273</id><published>2007-12-07T22:25:00.000-08:00</published><updated>2007-12-07T22:52:01.461-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='find'/><category scheme='http://www.blogger.com/atom/ns#' term='loading'/><category scheme='http://www.blogger.com/atom/ns#' term='deep'/><category scheme='http://www.blogger.com/atom/ns#' term='include'/><category scheme='http://www.blogger.com/atom/ns#' term='eager'/><title type='text'>ActiveRecord find - Eager loading -  :include - deep hierarchy of associations</title><content type='html'>While including a deep hierarchy of associations, I found a strange issue. Here is a contrived bit of code to describe the issue:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Post.find(:all, :include =&gt; [{ :comments =&gt; [:replies, { :author =&gt; :gravatar }]  } ])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A comment has_many replies which I want to pull in via eager loading. At the same time I also want to pull in the author and gravatar pictures.&lt;br /&gt;&lt;br /&gt;The issue here is  you can only have one argument  that is a  key-value pair and should be the last one. So the following doesn't seem to work:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Post.find(:all, :include =&gt; [{ :comments =&gt; [ { :replies =&gt; :author}, { :author =&gt; :gravatar }]  } ])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;nor does this&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Post.find(:all, :include =&gt; [{ :comments =&gt; [{ :author =&gt; :gravatar }, :replies]  } ])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I will post an update when I figure out how to get the author for each reply eager loaded as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-2786918237139850273?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/2786918237139850273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=2786918237139850273' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2786918237139850273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2786918237139850273'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/12/activerecord-find-eager-loading-include.html' title='ActiveRecord find - Eager loading -  :include - deep hierarchy of associations'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-4843507004190357628</id><published>2007-11-29T18:15:00.000-08:00</published><updated>2009-01-07T22:14:42.557-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='finite'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='state machine'/><category scheme='http://www.blogger.com/atom/ns#' term='fsm'/><category scheme='http://www.blogger.com/atom/ns#' term='acts_as_state_machine'/><title type='text'>acts_as_state_machine enhancements</title><content type='html'>&lt;span style="font-size:85%;"&gt;Download the plugin enhancement  &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://cpatil.googlepages.com/acts_as_state_machine_overrides.rb"&gt;here&lt;/a&gt;. Drop it into the lib directory and do a require in the model.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;A project I am working on required me to use a state machine to manage the state of a model. After downloading acts_as_state_machine plugin and I set it up as mentioned &lt;a href="http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Though I liked the way the plugin sets up the state machine, it seemed to lack some functionality for my usage:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;To be able to define an override event that would allow the user to select the  state the model should go to.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;While performing the transition from one state to another state, perform some operation that is specific to the triad - event, : from,  :to&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Let me show you what I mean by extending the example mentioned &lt;a href="http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/"&gt;&lt;span style="text-decoration: underline;"&gt;here&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; script/generate model Person shirt_color:string trouser_type:string status:string&lt;br /&gt;%&gt; rake db:migrate&lt;br /&gt;&lt;br /&gt;%&gt; emacs -nw app/models/person.rb&lt;br /&gt;&lt;br /&gt;require 'acts_as_state_machine_overrides'&lt;br /&gt;&lt;br /&gt;class Person &amp;lt; ActiveRecord::Base&lt;br /&gt;&lt;br /&gt;acts_as_state_machine :initial =&gt; :sleeping, :column =&gt; 'status'&lt;br /&gt;state :sleeping&lt;br /&gt;state :showering&lt;br /&gt;state :working&lt;br /&gt;state :dating&lt;br /&gt;&lt;br /&gt;event :shower do&lt;br /&gt;transitions :from =&gt; :sleeping, :to =&gt; :showering&lt;br /&gt;transitions :from =&gt; :working, :to =&gt; :showering&lt;br /&gt;transitions :from =&gt; :dating, :to =&gt; :showering&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;event :work do&lt;br /&gt;transitions :from =&gt; :showering, :to =&gt; :working&lt;br /&gt;# Going to work before showering?  Stinky.&lt;br /&gt;transitions :from =&gt; :sleeping, :to =&gt; :working&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;event :date do&lt;br /&gt;transitions :from =&gt; :showering, :to =&gt; :dating&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;event :sleep do&lt;br /&gt;transitions :from =&gt; :showering, :to =&gt; :sleeping&lt;br /&gt;transitions :from =&gt; :working, :to =&gt; :sleeping&lt;br /&gt;transitions :from =&gt; :dating, :to =&gt; :sleeping&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;event :wakeup do&lt;br /&gt;transitions :from =&gt; :sleeping,   :to =&gt; [:showering, :working]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;event :dress do&lt;br /&gt;transitions  :from =&gt; :showering,   :to =&gt; [:working, :dating],&lt;br /&gt;:on_transition =&gt; :wear_clothes&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def wear_clothes(shirt_color, trouser_type)&lt;br /&gt;self.shirt_color = shirt_color&lt;br /&gt;self.trouser_type = trouser_type&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ok, I put in a lot of stuff in there to chew on. Lets discuss it one by one.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :wakeup do&lt;br /&gt;transitions :from =&gt; :sleeping,   :to =&gt; [:showering, :working]&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;I can wake up and either go take a shower, or go sit on my computer and start working. This implies I have two transitions in the event wakeup:&lt;br /&gt;&lt;br /&gt;a)  from sleeping   to   showering&lt;br /&gt;b)  from sleeping   to   working&lt;br /&gt;&lt;br /&gt;If I express this as&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :wakeup do&lt;br /&gt;transitions   :from =&gt; :sleeping,    :to =&gt; :showering&lt;br /&gt;transitions   :from =&gt; :sleeping,    :to =&gt; :working&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;%&gt; script/console&lt;br /&gt;&gt;&gt; p = Person.new({:shirt_color =&gt; 'red', :trouser_type =&gt; 'dress pants'})&lt;br /&gt;&gt;&gt; p.save!&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :sleeping&lt;br /&gt;&gt;&gt; p.wakeup!&lt;br /&gt;=&gt; true&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :showering&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;acts_as_state_machine simply picks up the first transition in this case. There is no way for me to wake up and start working, unless I create a new event for this transition and invoke it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;If you notice, these two transitions were already present in the &lt;a href="http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/"&gt;example&lt;/a&gt;, but were fired when the user called work! or shower!. And that makes complete sense for this particular example where for all incoming transitions into a state are modeled as the event - i.e. all transitions that end up in the state :working are bundled in the event :work. I call this bottom up approach, where you create events based on  incoming transitions for a state.  In complex state machines however, you are not always free to choose the event based on the :to state, rather the events are modeled after real life actions that users perform.  This is more like the top down approach, where you are creating events based on outgoing transitions from a state.  Does that make sense?  In any case, continuing on with this post.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So I extended acts_as_state_machine plugin to accept an array for the :to argument and allow the user to specify the next state to transition to when the event is fired.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :wakeup do&lt;br /&gt;transitions   :from =&gt; :sleeping,    :to =&gt; [:working, :showering]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;%&gt; script/console&lt;br /&gt;&gt;&gt; p = Person.find(:all).last&lt;br /&gt;&gt;&gt; p.set_initial_state&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :sleeping&lt;br /&gt;&gt;&gt; p.wakeup!(:next_state =&gt; 'working')&lt;br /&gt;=&gt; true&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :working&lt;br /&gt;&gt;&gt; p.set_initial_state&lt;br /&gt;=&gt; "sleeping"&lt;br /&gt;&gt;&gt; p.wakeup!(:next_state =&gt; 'showering')&lt;br /&gt;=&gt; true&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :showering&lt;br /&gt;&lt;/pre&gt;So now the user can be queried for the desired :to state.&lt;br /&gt;&lt;br /&gt;Did you notice the extension to the event method. It now accepts the an optional hash argument as its last argument. Yup, I said - as the last argument- . But more on that in a minute.&lt;br /&gt;&lt;br /&gt;So the new method signature is now event_name!(*args, [:next_state =&gt; ...]).&lt;br /&gt;&lt;br /&gt;Next, we consider the issue of performing some work during the transition. The existing acts_as_state_machine plugin assumes any work that needs to be done would be done as you enter, after and exit each state. But with our new addition above of multiple possible :to states, there might be some common work that needs to be done that is not specific to the final :to state.&lt;br /&gt;Case in point,  after I take a shower, I need to wear clothes before either going to work or on a date. The act of wearing clothes does not fit in either going to work or going on a date.&lt;br /&gt;&lt;br /&gt;I know what the counter-argument is going to be - :dress should be a state in itself and there should be a transition going from :showering to :dress and then transitions from :dress to :working and :dress to :dating. And then wearing the clothes should be done in the :dress state.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;state :dress , :enter =&gt; :wear_clothes&lt;br /&gt;&lt;br /&gt;event :dress do&lt;br /&gt;transitions :from =&gt; :showering, :to =&gt; :dress&lt;br /&gt;end&lt;br /&gt;event :work do&lt;br /&gt;transitions :from =&gt; :dress, :to =&gt; :working&lt;br /&gt;...&lt;br /&gt;end&lt;br /&gt;event :work do&lt;br /&gt;transitions :from =&gt; :dress, :to =&gt; :working&lt;br /&gt;...&lt;br /&gt;end&lt;br /&gt;event :date do&lt;br /&gt;transition :from =&gt; :dress, :to =&gt; :dating&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Good point! I don't really have an answer to that yet, just a gut feeling that creating a virtual state for every little action that needs to be performed may lead to an unnecessarily complex state machine. If the work that needs to be performed is not related to the domain of the model which is being considered, it will introduce unrelated states in model's state machine.&lt;br /&gt;I know from a purist pov all such logic should reside in the controller. But then you have the model domain logic creeping out into the controller where some actions may need to be performed based on the current state and the next state.&lt;br /&gt;In any case, I implemented the on_transition feature for my project and here it is:&lt;br /&gt;&lt;br /&gt;Similar to the :guard option for a transition, one can specify a :on_transition argument to the transitions call. The callback can be a symbol or a Proc. You can also specify arguments to the callback by specifying them when you fire the event. Oh, and the callback can also return a value back as shown below:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :dress do&lt;br /&gt;transitions  :from =&gt; :showering,   :to =&gt; [:working, :dating],&lt;br /&gt;:on_transition =&gt; :wear_clothes&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def wear_clothes(shirt_color, trouser_type)&lt;br /&gt;self.shirt_color = shirt_color&lt;br /&gt;self.trouser_type = trouser_type&lt;br /&gt;id&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;%&gt; script/console&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :showering&lt;br /&gt;&gt;&gt; success, ret_val = p.dress!("blue", "jeans", :next_state =&gt; :working)&lt;br /&gt;=&gt; [true, 10001]&lt;br /&gt;&gt;&gt; p.current_state&lt;br /&gt;=&gt; :working&lt;br /&gt;&gt;&gt; p.shirt_color&lt;br /&gt;=&gt; "blue"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The on_transition callback is called after the guard callback. The return value of the on_transition callback in no way affects the transition. It is simply considered to be a side effect of the trasition.&lt;br /&gt;&lt;br /&gt;Oh and one more thing, the :from argument in the transitions call can be an array as well (this was part of the original acts_as_state_machine plugin). So you could do :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :sleep do&lt;br /&gt;transitions :from =&gt; [:showering, :working, :dating], :to =&gt; :sleeping, :guard =&gt; :brush_teeth&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With the above enhancements, you can now do&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;event :dress do&lt;br /&gt;transitions :from =&gt; [:showering, :sleeping], :to =&gt; [:working, :dating], :on_transition =&gt; :wear_clothes&lt;br /&gt;&lt;/pre&gt;Update: I forgot to mention these enhancements also include a method called next_events_for_current_state that I picked up from &lt;a href="http://pastie.caboo.se/19475"&gt;here&lt;/a&gt;, and fixed it to return the event names rather than the next states.&lt;br /&gt;&lt;br /&gt;Note: I haven't tested this rigorously, so if you do find something amiss, drop me a note.&lt;br /&gt;&lt;br /&gt;Njoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-4843507004190357628?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/4843507004190357628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=4843507004190357628' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4843507004190357628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/4843507004190357628'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/11/actsasstatemachine-enhancements.html' title='acts_as_state_machine enhancements'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-1971688070042166854</id><published>2007-11-16T13:07:00.001-08:00</published><updated>2007-11-16T13:21:33.605-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='updater'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='style'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>IE issue - style tag embedded in ajax response not parsed</title><content type='html'>While working on a recent project, my rails application was returning a html snippet with an embedded style tag in response to an ajax request. Firefox displayed the updated html content perfectly, but IE refused to play nice.&lt;br /&gt;&lt;br /&gt;This issue is documented &lt;a href="http://dev.rubyonrails.org/ticket/8282"&gt;here&lt;/a&gt;  and a solution has also been provided.  I use YUI so I updated the code to use YAHOO.env.ua for browser detection.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;      applyStyles: function(rawHTML) {&lt;br /&gt;         if (YAHOO.env.ua.gecko &gt; 0) return;&lt;br /&gt;         var headEl = null;  // lazy-load&lt;br /&gt;&lt;br /&gt;         // find all styles in the string&lt;br /&gt;         var styleFragRegex = '&amp;lt;style[^&amp;gt;]*&gt;([\u0001-\uFFFF]*?)&amp;lt;/style&amp;gt;';&lt;br /&gt;         var matchAll = new RegExp(styleFragRegex, 'img');&lt;br /&gt;         var matchOne = new RegExp(styleFragRegex, 'im');&lt;br /&gt;         var styles = (rawHTML.match(matchAll) || []).map(function(tagMatch) {&lt;br /&gt;            return (tagMatch.match(matchOne) || ['', ''])[1];&lt;br /&gt;         });&lt;br /&gt;&lt;br /&gt;         // add all found style blocks to the HEAD element.&lt;br /&gt;         for (i = 0; i &lt; styles.length; i++) {&lt;br /&gt;            if (!headEl) {&lt;br /&gt;               headEl = document.getElementsByTagName('head')[0];&lt;br /&gt;               if (!headEl){&lt;br /&gt;                  return;&lt;br /&gt;               }&lt;br /&gt;            }&lt;br /&gt;            var newStyleEl = document.createElement('style');&lt;br /&gt;            newStyleEl.type = 'text/css';&lt;br /&gt;            if (YAHOO.env.ua.ie &gt; 0){&lt;br /&gt;               newStyleEl.styleSheet.cssText = styles[i];&lt;br /&gt;            } else {&lt;br /&gt;               var cssDefinitionsEl = document.createTextNode(styles[i]);&lt;br /&gt;               newStyleEl.appendChild(cssDefinitionsEl);&lt;br /&gt;            }&lt;br /&gt;            headEl.appendChild(newStyleEl);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;&lt;/blockquote&gt;Njoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-1971688070042166854?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/1971688070042166854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=1971688070042166854' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1971688070042166854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1971688070042166854'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/11/ie-issue-style-tag-embedded-in-ajax.html' title='IE issue - style tag embedded in ajax response not parsed'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-2930546709576888496</id><published>2007-11-08T18:05:00.000-08:00</published><updated>2007-11-08T18:43:45.597-08:00</updated><title type='text'>attachement_fu - size column</title><content type='html'>While using &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/README"&gt;attachement_fu migration&lt;/a&gt; , I ran into the issue of 'size' being a reserved word in Oracle and kept getting the following error while running the migration:&lt;br /&gt;&lt;pre&gt;OCIError: ORA-00904: : invalid identifier:&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I got around it by naming the database column to 'asize' instead of 'size' in my database migration script and then adding an alias_attribute (&gt;= rails 1.2) to my model as&lt;br /&gt;&lt;pre&gt; alias_attribute :size, :asize&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-2930546709576888496?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/2930546709576888496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=2930546709576888496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2930546709576888496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2930546709576888496'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/11/attachementfu-size-column.html' title='attachement_fu - size column'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5820246775585847207</id><published>2007-10-25T18:30:00.002-07:00</published><updated>2007-10-25T18:44:28.726-07:00</updated><title type='text'>Stepping through your rails action code</title><content type='html'>For a long time I couldn't figure out what I could do with breakpoint. Other than running console like operations and inspecting instance variables, I couldn't seem to do much. So I relied mostly on logger.warn and console kind of debugging. Of course, I didn't have to debug much since I write a lot of tests ;)&lt;br /&gt;&lt;br /&gt;I come from perl world which has an awesome debugger available. I wanted to be able to step through the code and inspect my local variables in a loop and break on conditionals etc.&lt;br /&gt;&lt;br /&gt;Recently I  found &lt;a href="http://www.datanoise.com/articles/2006/7/12/tutorial-on-ruby-debug"&gt;ruby-debug&lt;/a&gt; and it seems to do all the things I have been wanting to do.&lt;br /&gt;&lt;br /&gt;The debugger drops me in the action and much to my delight I could inspect loop variables and break on conditionals. Inspecting variables is easy using the command "p".&lt;br /&gt;I ran irb at the rdb prompt and it dropped me into a  script/console like environment. The scope is still at the action. Much much better than where breakpoint drops me (lib/breakpoint).&lt;br /&gt;&lt;br /&gt;Check it out. I know it will make my life a lot more easier now.&lt;br /&gt;&lt;br /&gt;Njoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5820246775585847207?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5820246775585847207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5820246775585847207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5820246775585847207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5820246775585847207'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/stepping-through-your-rails-action-code.html' title='Stepping through your rails action code'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-7909002048157645063</id><published>2007-10-18T23:14:00.000-07:00</published><updated>2010-05-04T15:56:46.046-07:00</updated><title type='text'>ruby group_by</title><content type='html'>I often need to convert an array of objects into a hash, indexed by some attribute of the objects.&lt;br /&gt;&lt;br /&gt;For e.g. for a task list, each task is an object consisting of&lt;br /&gt;- type (e.g grocery, auto)&lt;br /&gt;- name  (e.g. Safeway, Lucky, OSH)&lt;br /&gt;- notes&lt;br /&gt;&lt;br /&gt;So a task list may look like&lt;br /&gt;&lt;blockquote&gt;[ &lt;br /&gt;    [  :type =&gt; :grocery,   :name =&gt; :safeway,     :notes =&gt; "buy some milk"  ],&lt;br /&gt;    [     :type =&gt; :grocery,      :name =&gt; :lucky          :notes =&gt; "buy halloween candy" ],&lt;br /&gt;   [     :type =&gt; :auto,         :name =&gt; :costco        :notes =&gt; "buy tires for the acura"  ]&lt;br /&gt;]&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;For display purposes I would like to organize the tasks by their type and then by names.&lt;br /&gt;&lt;br /&gt;Updated: Rails makes it so easy :)&lt;br /&gt;&lt;blockquote&gt;@tasks = {}&lt;br /&gt;TaskList.find(:all).group_by(&amp;amp;:type) do |type, subtasks|&lt;br /&gt;  @tasks[type] = subtasks.group_by(&amp;amp;:name)&lt;br /&gt;end&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-7909002048157645063?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/7909002048157645063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=7909002048157645063' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7909002048157645063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7909002048157645063'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/ruby-groupby.html' title='ruby group_by'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-1829226342405035256</id><published>2007-10-10T21:49:00.000-07:00</published><updated>2007-10-10T22:30:50.270-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='helper'/><title type='text'>escape_javascript goodness</title><content type='html'>I was trying to print some javascript in application .rhtml and wanted to use a link_to helper to print a link.&lt;br /&gt;&lt;blockquote&gt;var user = &lt;%= current_user.json_user_data %&gt;;&lt;br /&gt;$('welcome_p').innerHTML = "Welcome " + user.login + '! ( &lt;%= link_to("Sign out", session_path(), :method =&gt; :delete, :class =&gt; "wlcmLnk")) -%&gt; )';&lt;/blockquote&gt;This resulted in an error as link_to expanded to&lt;br /&gt;&lt;blockquote&gt; $('welcome_p').innerHTML = "Welcome " + ud.login + '! ( &amp;lt;a href="/session" class="wlcmLnk" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit();return false;"&amp;gt;Sign out&amp;lt;/a&amp;gt; )';&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The single quotes are not escaped :(&lt;br /&gt;&lt;br /&gt;But not to worry. escape_javascript will do the needful. It escapes carrier returns and single and double quotes.&lt;br /&gt;&lt;blockquote&gt;$('welcome_p').innerHTML = "Welcome " + ud.login + '! ( &amp;lt;a href=\"/session\" class=\"wlcmLnk\" onclick=\"var f = document.createElement(\'form\'); f.style.display = \'none\'; this.parentNode.appendChild(f); f.method = \'POST\'; f.action = this.href;var m = document.createElement(\'input\'); m.setAttribute(\'type\', \'hidden\'); m.setAttribute(\'name\', \'_method\'); m.setAttribute(\'value\', \'delete\'); f.appendChild(m);f.submit();return false;\"&amp;gt;Sign out&amp;lt;/a&amp;gt; )';&lt;/blockquote&gt;&lt;br /&gt;Njoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-1829226342405035256?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/1829226342405035256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=1829226342405035256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1829226342405035256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1829226342405035256'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/escapejavascript-goodness.html' title='escape_javascript goodness'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8125193068409214089</id><published>2007-10-09T21:12:00.000-07:00</published><updated>2007-10-09T23:39:19.791-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='location'/><category scheme='http://www.blogger.com/atom/ns#' term='popup'/><category scheme='http://www.blogger.com/atom/ns#' term='modalbox'/><category scheme='http://www.blogger.com/atom/ns#' term='xy'/><title type='text'>(re)Positionable Modalbox 1.5.5.1 updates</title><content type='html'>Download :&lt;a href="http://cpatil.googlepages.com/modalbox.js"&gt;&lt;br /&gt;modalbox.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/modalbox.css"&gt;modalbox.css&lt;br /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;(let me know if the above links don't work. I am still trying to figure out the best way to allow file downloads from blogspot).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;A quick post to describe my changes to modalbox.js:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- (re)Positionable&lt;/span&gt;&lt;br /&gt;A user can position Modalbox by specifying the CSS position properties (top, left, right, bottom)&lt;br /&gt;as&lt;br /&gt;Modalbox.show(content, {title: 'my positioned modalbox', top: '200px', left: '100px'});&lt;br /&gt;and then ...&lt;br /&gt;Modalbox.show(content, {title:'my re-positioned modalbox', top: '100px',  right: '100px'});&lt;br /&gt;&lt;br /&gt;If the CSS position properties are not specified, modalbox pops up in the default position.&lt;br /&gt;If the left and right properties are not specified, the modalbox pops up in the horizontal center.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- enable_rjs&lt;/span&gt;&lt;br /&gt;Modalbox treats any content returned by a http request to be html + script. However this craps out with Rails rjs. enable_rjs enables the rjs support so you can do (a bit contrived, but you get the idea)&lt;br /&gt;&lt;blockquote&gt;  respond_to do |format|&lt;br /&gt;format.html {&lt;br /&gt;     ...&lt;br /&gt;}&lt;br /&gt;format.js {&lt;br /&gt;  new_form = render_to_string(:partial =&gt; 'new', :layout =&gt; false)&lt;br /&gt;  render :update do |page|&lt;br /&gt;    page.call 'Modalbox._insertContent', new_form, { :top =&gt; '50px', :right =&gt; '100&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;px&lt;/span&gt;'}.to_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;json&lt;/span&gt;&lt;br /&gt;   page.call '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Modalbox&lt;/span&gt;._&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;putContent&lt;/span&gt;'&lt;br /&gt;  end&lt;br /&gt;}&lt;br /&gt;end&lt;/blockquote&gt;The invocation is&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Modalbox&lt;/span&gt;.show(content, { enable_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;rjs&lt;/span&gt;: true});&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- scroll bars disappear in IE 6&lt;/span&gt;&lt;br /&gt;This is described in detail &lt;a href="http://justbarebones.blogspot.com/2007/09/ie-6-issues-with-modalbox-155.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Please note that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Modalbox&lt;/span&gt; behaves like a singleton class. So if you set an option for a content, you need to explicitly reset that option to disable it for subsequent content.&lt;br /&gt;For e.g.&lt;br /&gt;Modalbox.show('/some_rjs_action', {enable_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;rjs&lt;/span&gt;: true});&lt;br /&gt;and then ...&lt;br /&gt;Modalbox.show('/some_action_that_returns_html', {enable_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;rjs&lt;/span&gt;: false});&lt;br /&gt;&lt;br /&gt;Let me know if you find any issues.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Njoy&lt;/span&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8125193068409214089?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8125193068409214089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8125193068409214089' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8125193068409214089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8125193068409214089'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/repositionable-modalbox-1551-updates.html' title='(re)Positionable Modalbox 1.5.5.1 updates'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5636050254435492319</id><published>2007-10-05T00:22:00.000-07:00</published><updated>2007-10-26T15:16:37.312-07:00</updated><title type='text'>Copy model data between databases</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;Update: I have modified the task to use save_with_valdation(false) and made it available&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;as a download &lt;/span&gt;&lt;a style="color: rgb(255, 0, 0);" href="http://cpatil.googlepages.com/clonedata.rake"&gt;here&lt;/a&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is an update on the &lt;a href="http://justbarebones.blogspot.com/2007/10/copy-data-between-databases-using.html"&gt;post &lt;/a&gt;I made yesterday about how easy it is to copy model data between production and development databases.&lt;br /&gt;&lt;br /&gt;The problem with the approach mentioned &lt;a href="http://alistairisrael.wordpress.com/2007/09/07/using-rails-console-to-copy-records-across-databases/"&gt;here &lt;/a&gt;is that the id of the original model data is not preserved. As a result, if you copy models with relationships defined using foreign keys, the relationships are not maintained.&lt;br /&gt;&lt;br /&gt;I found that instead of using [model].create, I can use [model].new and then set the id explicitly.&lt;br /&gt;&lt;blockquote&gt;   model_data.each do |m|&lt;br /&gt;   new =  model_data.new m.attributes&lt;br /&gt;   new.id = m.id&lt;br /&gt;   new.save!&lt;br /&gt; end&lt;/blockquote&gt;I wrote up a rake task to do something like&lt;br /&gt;&lt;blockquote&gt; rake  db:cloneModelData   MODEL=User,Account BATCH=Y&lt;br /&gt;&lt;/blockquote&gt;And the task is&lt;br /&gt;&lt;blockquote&gt;namespace :db do&lt;br /&gt;desc "Clone the data associated with a model from the production database to the development database.\n\n" +&lt;br /&gt;     "                                # If the development database contains any data related to the model, it is purged before the copy is made.\n" +&lt;br /&gt;     "                                # Specify the model class name on the command line as MODEL=X,Y,Z (no spaces)\n" +&lt;br /&gt;     "                                # Source database as SOURCE=db (production by default)\n" +&lt;br /&gt;     "                                # Destination database as DESTINATION=db  (development by default)\n\n" +&lt;br /&gt;     "                                # To enable batch mode BATCH=Y   (By default, the task queries the user to view the yaml and \n" +&lt;br /&gt;     "                                #                                 write it to a file (just in case-call me chicken if you wish)\n" +&lt;br /&gt;     "                                # e.g. rake db:cloneModelData MODEL=User,Account,Post BATCH=Y\n"&lt;br /&gt;task :cloneModelData =&gt; :environment do&lt;br /&gt;&lt;br /&gt;  batchmode = ENV['BATCH'] ? ENV['BATCH'] =~ /^y$/i : false&lt;br /&gt;  sourcedb = ENV['SOURCE'] || 'production'&lt;br /&gt;  puts "Connecting to source database '#{sourcedb}'"&lt;br /&gt;  ActiveRecord::Base.establish_connection(sourcedb)&lt;br /&gt;&lt;br /&gt;  unless ENV['MODEL']&lt;br /&gt;    print  "Please specify the model class name(s) seperated by commas: "&lt;br /&gt;    model_names = $stdin.gets.strip&lt;br /&gt;  else&lt;br /&gt;    model_names = ENV['MODEL'].strip&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  data = {}&lt;br /&gt;  model_names.split(/,/).each do |model_name|&lt;br /&gt;&lt;br /&gt;    begin&lt;br /&gt;      klass = Kernel.const_get model_name&lt;br /&gt;    rescue&lt;br /&gt;      raise "Hmm unable to get a Class object corresponding to #{model_name}. Check if you specified the correct model name: #{$!}"&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    unless klass.superclass == ActiveRecord::Base&lt;br /&gt;      raise "#{model_name}.superclass (#{klass.superclass}) is not ActiveRecord::Base"&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    puts "\nCollecting data for Model Class - #{model_name}"&lt;br /&gt;&lt;br /&gt;    # Collect all the data from te production database&lt;br /&gt;    data[model_name] = klass.find(:all)&lt;br /&gt;    puts "Found #{data[model_name].length} records in the #{sourcedb} database"&lt;br /&gt;&lt;br /&gt;    unless batchmode&lt;br /&gt;      print "\nDo you want to see a yaml dump? [y|N]: "&lt;br /&gt;      if $stdin.gets.strip =~ /^y/i&lt;br /&gt;        puts data[model_name].to_yaml&lt;br /&gt;      end&lt;br /&gt;      print "\nDo you want to direct the yaml dump to a file? [Y|n]: "&lt;br /&gt;      unless $stdin.gets.strip =~ /^n/i&lt;br /&gt;        print "\nPlease specify the file name : "&lt;br /&gt;        File.open($stdin.gets.strip, 'w') do |f|&lt;br /&gt;          f.write data[model_name].to_yaml&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  destdb = ENV['DESTINATION'] || 'development'&lt;br /&gt;  puts "\n--------------------------------------\n\nEstablising connection with the '#{destdb}' database\n\n"&lt;br /&gt;&lt;br /&gt;  ActiveRecord::Base.establish_connection(destdb)&lt;br /&gt;&lt;br /&gt;  puts "Now deleting model related data from the #{destdb} db\n"&lt;br /&gt;&lt;br /&gt;  data.keys.each do |model_name|&lt;br /&gt;&lt;br /&gt;    klass = Kernel.const_get model_name&lt;br /&gt;&lt;br /&gt;    olddata = klass.find(:all)&lt;br /&gt;&lt;br /&gt;    puts "\nFound #{olddata.length} #{model_name} records in the #{destdb} database"&lt;br /&gt;    unless batchmode&lt;br /&gt;      print "Do you want to see a yaml dump? [y|N]: "&lt;br /&gt;      if $stdin.gets.strip =~ /^y/i&lt;br /&gt;        puts olddata.to_yaml&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    puts "Deleting old data"&lt;br /&gt;    olddata.each {|f| f.destroy}&lt;br /&gt;&lt;br /&gt;    puts "Now copying the #{sourcedb} model data into the #{destdb} database"&lt;br /&gt;    print "Copying #{model_name} records: "&lt;br /&gt;    i = 0&lt;br /&gt;    data[model_name].each do |d|&lt;br /&gt;      begin&lt;br /&gt;        print "#{ i+=1}, "&lt;br /&gt;&lt;br /&gt;        obj = klass.new d.attributes&lt;br /&gt;        obj.id = d.id&lt;br /&gt;        obj.save!&lt;br /&gt;&lt;br /&gt;        #klass.reflect_on_all_associations.each { |a|&lt;br /&gt;        #      puts classname + " -&gt; " + a.name.to_s.camelize.singularize + " [label="+a.macro.to_s+"]"&lt;br /&gt;        #}&lt;br /&gt;&lt;br /&gt;      rescue&lt;br /&gt;        raise "Error saving model data: #{$!}"&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    puts "\nDone copying #{model_name}\n"&lt;br /&gt;  end&lt;br /&gt;  puts "\nDone."&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;Njoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5636050254435492319?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5636050254435492319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5636050254435492319' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5636050254435492319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5636050254435492319'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/copy-model-data-between-databases.html' title='Copy model data between databases'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6509594601377835895</id><published>2007-10-04T00:44:00.000-07:00</published><updated>2007-10-26T15:15:46.866-07:00</updated><title type='text'>Copy data between databases using script/console</title><content type='html'>A quick blog about how &lt;a href="http://alistairisrael.wordpress.com/2007/09/07/using-rails-console-to-copy-records-across-databases/"&gt;easy&lt;/a&gt; it is to copy data between databases using script/console.&lt;br /&gt;For e.g. I copy data from production server to the development server below:&lt;br /&gt;&lt;br /&gt;% script/console production -s&lt;br /&gt;&gt; projects = Project.find(:all)&lt;br /&gt;&gt; ActiveRecord::Base.establish_connection(:development)&lt;br /&gt;&gt; projects.each {|p| Project.create p.attributes}&lt;br /&gt;&gt; CtrlD&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6509594601377835895?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6509594601377835895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6509594601377835895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6509594601377835895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6509594601377835895'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/10/copy-data-between-databases-using.html' title='Copy data between databases using script/console'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3662444561736219053</id><published>2007-09-28T22:01:00.000-07:00</published><updated>2007-10-09T22:44:14.703-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='popup'/><category scheme='http://www.blogger.com/atom/ns#' term='modalbox'/><title type='text'>IE 6 issues with Modalbox 1.5.5 + Protoculous 1.0.2</title><content type='html'>&lt;a href="http://justbarebones.blogspot.com/2007/10/repositionable-modalbox-1551-updates.html"&gt;Update&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I had two issues with Modalbox 1.5.5. on IE-6, and this post describes how I fixed them.&lt;br /&gt;a) IE 6 hangs - page related issue&lt;br /&gt;b) IE 6 vertical scrollbar dissappears when Modalbox is displayed - Modalbox issue&lt;br /&gt;&lt;br /&gt;I wanted to use Ajax popus for a user signin-signup flow on a website I am building. Since I was already using prototype and effects from prototculous 1.0.2, I looked around for prototype powered popups. I found &lt;a href="http://www.wildbit.com/labs/modalbox/"&gt;Modalbox&lt;/a&gt; and immediately liked its capabilities. The effects are configurable, and the content to be displayed can be specified as a url, plain html, a dom node or a javascript html object. The Interface api is elegant in its simplicity.&lt;br /&gt;Thanks to Wildbit's team for releasing such a useful product to open source.&lt;br /&gt;&lt;br /&gt;The integration with my code was a snap. I fired up the server and tested the code in Firefox. It worked beautifully.&lt;br /&gt;But IE 6/SP2 was another story.&lt;br /&gt;As soon as I clicked on the link to show the Modalbox popup, IE 6 froze.&lt;br /&gt;&lt;br /&gt;IE 6/SP2 had worked fine (except that it complains about a js error on page load) on modalbox's home page, so the problem must be my website's page.&lt;br /&gt;If I turned off modalbox transitions, the popup worked, so I figured effects.js was having some problem with the page css.&lt;br /&gt;&lt;br /&gt;On digging through,  I zeroed in on the padding property that was defined on the body element. It seemed to be causing the IE 6 hang:&lt;br /&gt;&lt;blockquote&gt;body {&lt;br /&gt;  margin: auto;&lt;br /&gt;  padding: 15px 0px 25px 0px;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;On removing this property, IE 6 worked fine. Weird huhn!&lt;br /&gt;&lt;br /&gt;But another nagging problem remained.&lt;br /&gt;On IE 6, whenever the modalbox overlay appeared, the vertical scrollbar on my web page would disappear. On canceling the popup, the scrollbar would reappear. If you visit &lt;a href="http://www.wildbit.com/labs/modalbox/"&gt;modalbox's home page&lt;/a&gt;, you will see what I am talking about. It was distracting to me, so I set out to fix it.&lt;br /&gt;&lt;br /&gt;On digging through, I found the following function in modalbox.js:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;  // For IE browsers -- IE requires height to 100% and overflow hidden (taken from lightbox)&lt;br /&gt;  _prepareIE: function(height, overflow){&lt;br /&gt;     var body = document.getElementsByTagName('body')[0];&lt;br /&gt;     body.style.height = height;&lt;br /&gt;     body.style.overflow = overflow;&lt;br /&gt;&lt;br /&gt;     var html = document.getElementsByTagName('html')[0];&lt;br /&gt;     html.style.height = height;&lt;br /&gt;     html.style.overflow = overflow;&lt;br /&gt;  },&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The code is setting the body height to 100% which caused the scrollbar to disappear.&lt;br /&gt;&lt;br /&gt;I commented out the function, but then found that the MB_overlay div didn't cover the entire screen height.&lt;br /&gt;So I wrote up some code to calculate the screen height and width in pixels and set the div size explictly.&lt;br /&gt;&lt;br /&gt;To summarize, I removed all references which set height (and width) to 100% on the body, html and MB_overlay elements. Instead I calculate the screen size and set MB_overlay size  accordingly.&lt;br /&gt;&lt;br /&gt;The files can be downloaded from here&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/modalbox.js"&gt;modalbox.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cpatil.googlepages.com/modalbox.css"&gt;modalbox.css&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This fixed the scrollbar issue for me.&lt;br /&gt;Hope this is of help to others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3662444561736219053?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3662444561736219053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3662444561736219053' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3662444561736219053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3662444561736219053'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/09/ie-6-issues-with-modalbox-155.html' title='IE 6 issues with Modalbox 1.5.5 + Protoculous 1.0.2'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-7817247154661486707</id><published>2007-09-20T15:19:00.000-07:00</published><updated>2007-09-20T15:49:31.080-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='replace_html'/><category scheme='http://www.blogger.com/atom/ns#' term='assert_rjs'/><category scheme='http://www.blogger.com/atom/ns#' term='arts'/><title type='text'>Arts patch for assert_rjs :replace_html bug</title><content type='html'>You can use the slick Rails&lt;a href="http://glu.ttono.us/articles/2006/05/29/guide-test-driven-rjs-with-arts"&gt; Arts&lt;/a&gt; plugin to test your rjs renders. But the plugin breaks while testing assert_rjs :replace_html&lt;br /&gt;&lt;br /&gt;If you have the following construct in your action method:&lt;br /&gt;&lt;blockquote&gt;   render :update do |page|&lt;br /&gt;     page['elemid'].replace_html   some_string&lt;br /&gt; end&lt;br /&gt;&lt;/blockquote&gt;The Rails Javascript helper replaces the replace_html call with the following call:&lt;br /&gt;&lt;blockquote&gt;$('elemid').update(some_string)&lt;/blockquote&gt;This breaks the arts plugin which only expects&lt;br /&gt;Element.update('elemid', some_string)&lt;br /&gt;&lt;br /&gt;So here is a simple patch to make your assert_rjs :replace_html to work.&lt;br /&gt;&lt;blockquote&gt;53,54c53,55&lt;br /&gt;&lt;&gt;           #assert_match Regexp.new("Element.update(.*#{div}.*,.*#{content.source}.*);"),&lt;br /&gt;&gt;           assert_match /(\$\(['"]#{div}['"]\).update\(|Element.update\(.*#{div}.*,)['"].*#{content.source}.*['"]\);/, #'&lt;br /&gt;&gt;                                  @response.body&lt;br /&gt;56c57,59&lt;br /&gt;&lt;&gt;         #assert_response_contains("Element.update(\"#{div}\", #{content});",&lt;br /&gt;&gt;&lt;br /&gt;&gt;         assert_response_contains(["Element.update(\"#{div}\", #{content});", %Q!$("#{div}").update(#{content});!],&lt;br /&gt;63c66,67&lt;br /&gt;&lt;&gt;       #assert_match Regexp.new("Element.update(.*#{div}.*,.*?);"), @response.body&lt;br /&gt;&gt;       assert_match /(\$\(['"]#{div}['"]\).update\(['"]|Element.update\(.*#{div}.*,['"]).*?\);/, @response.body&lt;br /&gt;98c102,107&lt;br /&gt;&lt;&gt;     if str.class == Array&lt;br /&gt;&gt;       strA = str&lt;br /&gt;&gt;     else&lt;br /&gt;&gt;       strA = [str]&lt;br /&gt;&gt;     end&lt;br /&gt;&gt;     assert strA.detect {|s| @response.body.to_s.index(s) != nil }, message&lt;br /&gt;133c142&lt;br /&gt;&lt;&gt; end&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-7817247154661486707?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/7817247154661486707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=7817247154661486707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7817247154661486707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7817247154661486707'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/09/arts-patch-for-assertrjs-replacehtml.html' title='Arts patch for assert_rjs :replace_html bug'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6210828372410591340</id><published>2007-09-06T16:51:00.001-07:00</published><updated>2007-12-11T18:31:00.700-08:00</updated><title type='text'>RoR,  Oracle, sqlplus and life</title><content type='html'>&lt;span style="font-style:italic;"&gt;Update: Read &lt;a href="http://justbarebones.blogspot.com/2007/12/installing-oracle-10g-express-edition.html"&gt;this&lt;/a&gt; if you want to use Oracle 10g Express edition on Linux 64 bit White box &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This took me some time to find, so I will document it for everyone's benefit.&lt;br /&gt;&lt;br /&gt;At work, I needed to use an Oracle database for my RoR apps.&lt;br /&gt;&lt;br /&gt;Here is a quick summary of steps to install the Ruby oci driver etc:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First download &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html"&gt;Oracle Instantclient&lt;/a&gt;  and install it to say /opt/oracle/10.2.0.3&lt;br /&gt;This makes connecting to Oracle a snap. Very useful indeed.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;setenv LD_LIBRARY_PATH  /opt/oracle/10.2.0.3&lt;br /&gt;setenv ORACLE_HOME /opt/oracle/10.2.0.3&lt;br /&gt;setenv NLS_LANG AMERICAN_AMERICA.UTF8&lt;br /&gt;&lt;br /&gt;# install oci driver&lt;br /&gt;wget http://rubyforge.org/frs/download.php/22320/ruby-oci8-1.0.0-rc3.tar.gz&lt;br /&gt;tar xvzf ruby-oci8-1.0.0-rc3.tar.gz&lt;br /&gt;cd ruby-oci8-1.0.0-rc3&lt;br /&gt;ruby setup.rb config -- --with-instant-client=/opt/oracle/10.2.0.3&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;test it&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%&gt; irb&lt;br /&gt;irb(main):001:0&gt; require 'oci8'&lt;br /&gt;=&gt; true&lt;br /&gt;irb(main):002:0&gt; exit&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Specify the following in your database.yml&lt;br /&gt;production:&lt;br /&gt;  adapter: oci&lt;br /&gt;  host: //dbHost:1521/oracle_instance&lt;br /&gt;  username: xxxx&lt;br /&gt;  password: xxxx&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;To use sqlplus to connect to the Oracle db&lt;br /&gt;&lt;br /&gt;sqlplus   username/password@//dbHost/Oracle_db_instance&lt;br /&gt;&lt;br /&gt;or (if you don't want the pwd to be visible in ps listings)&lt;br /&gt;&lt;br /&gt;sqlplus /NOLOG&lt;br /&gt;SQL*Plus: Release 10.2.0.3.0 - Production on Thu Sep 6 17:08:28 2007&lt;br /&gt;&lt;br /&gt;Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.&lt;br /&gt;&lt;br /&gt;SQL&gt; connect username/password@//dbHost/Oracle_db_instance&lt;br /&gt;&lt;br /&gt;No need to muck with any  tnsnames.ora.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6210828372410591340?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6210828372410591340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6210828372410591340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6210828372410591340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6210828372410591340'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/09/ror-oracle-sqlplus-and-life.html' title='RoR,  Oracle, sqlplus and life'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5018477852293560543</id><published>2007-09-06T16:45:00.000-07:00</published><updated>2007-09-06T16:50:46.022-07:00</updated><title type='text'>netstat</title><content type='html'>A quick blog after a brief hiatus:&lt;br /&gt;&lt;br /&gt;While trying to debug random lockups of our Oracle database server, I found a cool command to monitor the connections being served by a machine.&lt;br /&gt;&lt;br /&gt;I already knew about netstat and netstat -c which gives the user a continuous display of the connections.&lt;br /&gt;&lt;br /&gt;But I found &lt;a href="http://www.paganini.net/index.cgi/linux/netstat.html"&gt;another way&lt;/a&gt; to view the connections in real time using the watch command:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;watch -d "netstat -toupe 2&gt;/dev/null"&lt;br /&gt;&lt;/blockquote&gt;Pretty cool!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5018477852293560543?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5018477852293560543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5018477852293560543' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5018477852293560543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5018477852293560543'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/09/netstat.html' title='netstat'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-2869536086211137348</id><published>2007-08-15T14:37:00.000-07:00</published><updated>2007-08-15T15:01:20.316-07:00</updated><title type='text'>Rails - About your application's environment</title><content type='html'>I set up a rails instance yesterday on my linux box and started it up in the development mode as usual.&lt;br /&gt;From my windows box I accessed the main page (default with rails) of the application. I wanted to verify the environment that rails was loading. So I clicked on the "About your application's environment" link.&lt;br /&gt;&lt;br /&gt;I got an error message -&lt;br /&gt;For security purposes, this information is only available to local requests.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hmm, I knew I had started my server in the development mode and by default this mode considers all requests local.&lt;br /&gt;&lt;br /&gt;I doubled checked config/environments/development.rb and found the setting to be right...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Show full error reports and disable caching&lt;br /&gt;config.action_controller.consider_all_requests_local = true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hmm what is going on?&lt;br /&gt;&lt;br /&gt;From development.log I figured  the controller for this request to be rails/info with the action name as properties.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; grep -r "def properties" /usr/local/lib/ruby/gems/1.8/gems /*&lt;br /&gt;/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/builtin/rails_info/rails/info_controller.rb:  def properties&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ah! So I checked out info_controller.rb&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Rails::InfoController &lt; ActionController::Base&lt;br /&gt;  def properties&lt;br /&gt;    if local_request?&lt;br /&gt;      render :inline =&gt; Rails::Info.to_html&lt;br /&gt;    else&lt;br /&gt;      render :text =&gt; '&lt;p&gt;For security purposes, this information is only available to local requests.&lt;/p&gt;', :status =&gt; 500&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tracing local_request? led me to&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; grep -r 'def local_request?' /usr/local/lib/ruby/gems/1.8/gems/*&lt;br /&gt;/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/rescue.rb:      def local_request? #:doc:&lt;br /&gt;%&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Looking at local_request?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;      def local_request? #:doc:&lt;br /&gt;        [request.remote_addr, request.remote_ip] == ["127.0.0.1"] * 2&lt;br /&gt;      end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;it is clear that local_request? will return false in this case since I am accessing the page from a different machine.&lt;br /&gt;As I searched for local_request? again, I found this snippet in rescue.rb itself:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;      def rescue_action(exception)&lt;br /&gt;        log_error(exception) if logger&lt;br /&gt;        erase_results if performed?&lt;br /&gt;&lt;br /&gt;        if consider_all_requests_local || local_request?&lt;br /&gt;          rescue_action_locally(exception)&lt;br /&gt;        else&lt;br /&gt;          rescue_action_in_public(exception)&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ah ha! we need to add consider_all_requests_local to our properties action as well. So I popped open app/controller/application.rb and added the following snippet&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Rails::InfoController &lt; ActionController::Base&lt;br /&gt;  def properties&lt;br /&gt;    if consider_all_requests_local || local_request?&lt;br /&gt;      render :inline =&gt; Rails::Info.to_html&lt;br /&gt;    else&lt;br /&gt;      render :text =&gt; '&lt;p&gt;For security purposes, this information is only available to local requests.&lt;/p&gt;', :status =&gt; 500&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class ApplicationController &lt;  ActionController::Base&lt;br /&gt;  # Pick a unique cookie name to distinguish our session data from others'&lt;br /&gt;  session :session_key =&gt; '_ptracker_session_id'&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A server restart and I got the output I wanted:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="name"&gt;Ruby version&lt;/td&gt;&lt;td class="value"&gt;1.8.6 (x86_64-linux)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;RubyGems version&lt;/td&gt;&lt;td class="value"&gt;0.9.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Rails version&lt;/td&gt;&lt;td class="value"&gt;1.2.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Active Record version&lt;/td&gt;&lt;td class="value"&gt;1.15.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Action Pack version&lt;/td&gt;&lt;td class="value"&gt;1.13.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Action Web Service version&lt;/td&gt;&lt;td class="value"&gt;1.2.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Action Mailer version&lt;/td&gt;&lt;td class="value"&gt;1.3.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Active Support version&lt;/td&gt;&lt;td class="value"&gt;1.4.2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Application root&lt;/td&gt;&lt;td class="value"&gt;/home/xxxx/ror&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Environment&lt;/td&gt;&lt;td class="value"&gt;development&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="name"&gt;Database adapter&lt;/td&gt;&lt;td class="value"&gt;mysql&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hmm maybe I should submit a patch!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-2869536086211137348?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/2869536086211137348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=2869536086211137348' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2869536086211137348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/2869536086211137348'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/08/rails-about-your-applications.html' title='Rails - About your application&apos;s environment'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-5066502274305183841</id><published>2007-08-02T15:34:00.000-07:00</published><updated>2007-08-09T15:40:29.309-07:00</updated><title type='text'>ActiveDirectory (LDAP) integration with Rails - Update</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;Update: Replacing balance&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;So I managed to put together something in place:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &lt;iis&gt;                            &lt;-----&gt;           [ balance   &lt;-----&gt; Mongrel cluster ]&lt;br /&gt;  (ISAPI rewrite proxy)                                    (backend server - Vmware m/c)&lt;br /&gt;&lt;/iis&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The IIS proxy takes of single-sign on and LDAP authentication. I used &lt;a href="http://www.isapirewrite.com/docs"&gt;ISAPI rewrite proxy&lt;/a&gt; to rewrite requests to a virutal machine backend that hosts the actual rails cluster.  &lt;br /&gt;The rewrite rules look like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ISAPI/httpd.ini:&lt;br /&gt;RewriteCond URL (.*)&lt;br /&gt;RewriteHeader X-Forwarded-URL: .* $1&lt;br /&gt;&lt;br /&gt;RewriteCond Host: rails-backend(?:-dev)?(?:\.domain.com)?&lt;br /&gt;RewriteProxy (.*) http\://rails-backend:8081$1 [I,U,A]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On the backend side, rails-backend is a VMware guest that runs a Mongrel cluster of three Rails apps behind a load balancer balance (see the update above though).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;balance 8081 cadweb:8000 cadweb:8001 cadweb:8002 %&lt;br /&gt;&lt;br /&gt;# for debug use following&lt;br /&gt;# balance -d -f -p 8081 cadweb:8000 cadweb:8001 cadweb:8002 %&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The % at the end means to use a hash based routing. So the same client gets routed back to the same server for every request. &lt;span style="color: rgb(255, 0, 0);"&gt;Update - see the top of the post&lt;/span&gt;&lt;br /&gt;One thing I wished balance would do is filter incoming connections. In this case I would have like balance to restrict all incoming connections to the IIS proxy. I had to use iptables to do it.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;iptables -A INPUT -p tcp -s iis-proxy --dport 8081 -m state --state NEW,ESTABLISHED -j ACCEPT&lt;br /&gt;iptables -A INPUT -p tcp --dport 8081 -m state --state NEW,ESTABLISHED -j DROP&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A big issue with this solution is getting the list of access lists a user has rights to. And then use that information in rails somehow to limit which page can be shown to the user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-5066502274305183841?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/5066502274305183841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=5066502274305183841' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5066502274305183841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/5066502274305183841'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/08/activedirectory-ldap-integration-with.html' title='ActiveDirectory (LDAP) integration with Rails - Update'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6011476074119874151</id><published>2007-08-02T14:10:00.000-07:00</published><updated>2007-08-02T14:17:10.654-07:00</updated><title type='text'>csh - executing a unix cmd and checking for its exit status</title><content type='html'>Everyone knows how to check the exit status of a command invoked via csh/tcsh&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; cat mycmd&lt;br /&gt;#!/bin/csh -f&lt;br /&gt;exit 0;&lt;br /&gt;&lt;br /&gt;%&gt; cat wrapper.csh&lt;br /&gt;#!/bin/csh -f&lt;br /&gt;&lt;br /&gt;mycmd&lt;br /&gt;if ($status) then&lt;br /&gt;   echo "error executing mycmd"&lt;br /&gt;   exit 1&lt;br /&gt;endif&lt;br /&gt;echo "successful execution of mycmd"&lt;br /&gt;&lt;br /&gt;%&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But there is another easier way if you don't care about the actual value of the exit status.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; cat easier_wrapper.csh&lt;br /&gt;#!/bin/csh -f&lt;br /&gt;&lt;br /&gt;if ! { mycmd } then&lt;br /&gt;   echo "error executing mycmd"&lt;br /&gt;   exit 1&lt;br /&gt;endif&lt;br /&gt;echo "successful execution of mycmd"&lt;br /&gt;&lt;br /&gt;%&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice the use of curly braces around mycmd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6011476074119874151?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6011476074119874151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6011476074119874151' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6011476074119874151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6011476074119874151'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/08/csh-executing-unix-cmd-and-checking-for.html' title='csh - executing a unix cmd and checking for its exit status'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6858845574194517999</id><published>2007-07-25T18:28:00.000-07:00</published><updated>2007-09-10T08:57:36.588-07:00</updated><title type='text'>linux tidbit - Finding the working directory of a process</title><content type='html'>If you are working on multiple Ruby on rails apps, you will have at least 2-3 instances running on your machine at the same time. It is a chore to keep straight the port numbers with project directories (hmm maybe I should write a plugin for this :~))&lt;br /&gt;&lt;br /&gt;I was in a similar situation where I couldn't recall why a RoR instance was running on one of the ports.&lt;br /&gt;&lt;br /&gt;So I did a ps -auxww to get the process id of the process and then&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cp&gt;  cd /proc/&lt;pid&gt;[process_id]/cwd&lt;br /&gt;cp&gt;  pwd&lt;br /&gt;/home/cpatil/....&lt;br /&gt;&lt;br /&gt;&lt;/pid&gt;&lt;/pre&gt;&lt;br /&gt;Pretty cool!&lt;br /&gt;/proc is a virtual filesystem and allows you to peek inside the OS kernel at runtime and find information about the  processes running on the machine. Google for it,  a one time read is a must for all linux users, young and old.&lt;br /&gt;It is quite funky the way it is set up. For e.g. most files are 0 bytes and you need to do a cat to read it. Stuff like that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6858845574194517999?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6858845574194517999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6858845574194517999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6858845574194517999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6858845574194517999'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/07/linux-tidbit-finding-working-directory.html' title='linux tidbit - Finding the working directory of a process'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-1036935384982226230</id><published>2007-07-24T02:37:00.002-07:00</published><updated>2007-07-24T03:05:17.603-07:00</updated><title type='text'>Rails: Calling another action</title><content type='html'>It is interesting how Rails behaves when one action calls another as part of processing a request.&lt;br /&gt;&lt;br /&gt;Here is my test:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;app/controllers/test_controller.rb&lt;br /&gt;def action1&lt;br /&gt;@foo = "action1"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def action2&lt;br /&gt;@foo = "action2"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;app/view/test/action1.rhtml&lt;br /&gt;&amp;lt;h1&amp;gt;action1.rhtml&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;h2&amp;gt;&amp;lt;%= @foo %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;&lt;br /&gt;app/view/test/action2.rhtml&lt;br /&gt;&amp;lt;h1&amp;gt;action2.rhtml&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;h2&amp;gt;&amp;lt;%= @foo %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is what I observed when I call action2 from action1 like so:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def action1&lt;br /&gt;@foo = "action1"&lt;br /&gt;action2&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def action2&lt;br /&gt;@foo = "action1"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If none of the actions have a render explicitly defined, then calling action2 from action1 will simply execute the logic defined in the action2 method. The template that will be rendered will be action1.rhtml&lt;/li&gt;&lt;li&gt;If both of the actions have a render explictly defined, then calling action2 from action1 is a multi-render error.  It doesn't matter if you use render :template or render :action or just render.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If only action2 has an explicit render defined, then&lt;br /&gt;- action2 method is executed&lt;br /&gt;- if action2 calls a default template render, then action1.rhtml will be used as the template&lt;br /&gt;- if action2 calls a specific template, say render :action =&gt; 'action2', then action2.rhtml is used.&lt;br /&gt;Note that it is a multi-render error in this case if action1 also has an explicit render defined in it.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-1036935384982226230?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/1036935384982226230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=1036935384982226230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1036935384982226230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1036935384982226230'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/07/rails-calling-another-action.html' title='Rails: Calling another action'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-651185545202015431</id><published>2007-07-19T19:02:00.000-07:00</published><updated>2007-07-19T19:23:23.389-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Rails caching</title><content type='html'>Options :&lt;br /&gt;Page caching&lt;br /&gt;Action caching&lt;br /&gt;Fragment Caching&lt;br /&gt;&lt;br /&gt;Read these:&lt;a href="http://www.ibm.com/developerworks/web/library/wa-rails1/"&gt;&lt;br /&gt;Real World Rails series&lt;/a&gt;&lt;br /&gt;&lt;a href="http://scottstuff.net/presentations/rails-caching/"&gt;Content Caching in Rails&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;For fragment caching, use &lt;a href="http://svn.livsey.org/plugins/timed_fragment_cache/"&gt;timed_fragment_cache&lt;/a&gt; which allows the cached content to be expired automatically based on a timeout.&lt;br /&gt;&lt;br /&gt;I was thinking of allowing my users to  request an explicit rebuild of the page by forcing the cache to expire before the timeout. This could be done by providing an action which will simply expire the fragment and redirect back to the original action.&lt;br /&gt;However in the event that two users click on the rebuild request within say 1 minute of each other, I want the subsequent build request to be ignored automatically. I will take a stab at modifying the timed_fragment_cache plugin for doing this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-651185545202015431?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/651185545202015431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=651185545202015431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/651185545202015431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/651185545202015431'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/07/rails-caching.html' title='Rails caching'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3169324612552276615</id><published>2007-07-15T23:58:00.000-07:00</published><updated>2007-07-16T00:12:05.168-07:00</updated><title type='text'>SQL Query optimization</title><content type='html'>To begin optimization, select the SQL query that&lt;br /&gt;- returns max number of rows&lt;br /&gt;- has most number of executions&lt;br /&gt;- most I/O&lt;br /&gt;&lt;br /&gt;Optimizations:&lt;br /&gt;- The basic tenet is to avoid full table scans. Add an index to the fields mentioned in the where clause. Indexs are created as an additional file typically that the database can consult to filter the table based on the values of the corresponding field. Be careful, don't add to many indexes as every index requires an additional change to the database whenever data is inserted in the table. The indexs are typically stored as BTree indexes.&lt;br /&gt;&lt;br /&gt;Use EXPLAIN Select query... to examine if the database is using the indexes correctly.&lt;br /&gt;&lt;br /&gt;If you do any kind of operation on a field in the where clause, the full table is scanned since the field value for each record needs to be computed to be compared. As a result the index on such a field is a waste. Try using the field as is.&lt;br /&gt;&lt;br /&gt;- Joins should be ordered so that the table that has the max rows to be processed is filtered the most. The order is also imp. If you are joining A, B and C where C is 10 rows and A and B are 100000000 rows each, then it makes sense to join B and C first instead of joinging A and C first.&lt;br /&gt;Apply max filtering to table that has max rows.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Other Database trivia:&lt;br /&gt;1NF - normalization in which repeated fields (score1, team1, score2, team2) are moved into their own table. One to many relationship.&lt;br /&gt;2NF - normalization in which repeated values (publisher and publisher address for a list of books) are moved into their own table. Many to Many relationship.&lt;br /&gt;3NF - TO be written.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3169324612552276615?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3169324612552276615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3169324612552276615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3169324612552276615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3169324612552276615'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/07/sql-query-optimization.html' title='SQL Query optimization'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3149840658706850952</id><published>2007-07-07T22:22:00.000-07:00</published><updated>2007-07-07T22:31:40.827-07:00</updated><title type='text'>Some HTML Links</title><content type='html'>These were interesting links that I collected while doing some HTML UI design.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Extra spaces after HTML form - &lt;a href="http://www.cs.tut.fi/%7Ejkorpela/forms/extraspace.html"&gt;solution&lt;/a&gt;&lt;/li&gt;&lt;li&gt; Clearing spaces beneath floated elements - &lt;a href="http://css-discuss.incutio.com/?page=ClearingSpace"&gt;solution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Centering content  using CSS  - &lt;a href="http://dorward.me.uk/www/centre/"&gt;solution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HTML Tables - &lt;a href="http://www.w3.org/TR/html4/struct/tables.html"&gt;MUST READ&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3149840658706850952?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3149840658706850952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3149840658706850952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3149840658706850952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3149840658706850952'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/07/some-html-links.html' title='Some HTML Links'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-491398719801805178</id><published>2007-06-25T23:22:00.000-07:00</published><updated>2007-06-26T02:05:32.633-07:00</updated><title type='text'>Setting up Ubuntu 7.04 (Feisty) as  vmware host with a wireless card</title><content type='html'>Phew, after fighting with this setup for 3 days, I have managed to bring up Bridged networking to a wireless interface in a Ubuntu Feisty server. &lt;br /&gt;&lt;br /&gt;I am listing a short summary of my wanderings here so other users who are stuck at various places in the process can pick it up from there. There are a whole bunch of solutions out there which unfortunately trample over each other. &lt;br /&gt;&lt;br /&gt;I also want to thank all the users who contributed on this topic all over the internet. Awesome!!&lt;br /&gt;&lt;br /&gt;For the final solution mix, scroll down to the end of the post.&lt;br /&gt;&lt;br /&gt;-- &lt;span style="font-weight:bold;"&gt;My setup&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have an old HP DL-140 Proliant server sitting in my garage. I wanted to use it as a vmware host to run some development oses. Since the server is situated in the garage with no ethernet wiring, I decided to use a cheap D-Link DWLG510 802.11G card. &lt;br /&gt;&lt;br /&gt;I have a Hardware firewall/router that DHCP's for my entire Home LAN and my wireless access point is set up in the bridge mode to connect my wireless network to the ethernet network. This allows me to get a single network topology, allowing easy access to machines and their data.&lt;br /&gt;&lt;br /&gt;I wanted to set up the Ubuntu server so that the Guest VM's could bridge to the host's wireless interface and use DHCP to acquire dynamic IP address from the hardware router. &lt;br /&gt;&lt;br /&gt;[VMware Guest]  &lt;--&gt; (vmnet 0 bridge)  &lt;--&gt; [VMware host/Ubuntu]  &lt;--&gt; (Wireless NIC ath0) &lt;--&gt; [Wireless AP] &lt;--&gt; (ethernet) &lt;--&gt; [HW Router/DHCP] &lt;--&gt; WAN &lt;br /&gt;&lt;br /&gt;I wanted to be able to run multiple web servers  on these Guest VMs and reach any server using the IP address (or a dns name) directly instead of using natted ports.&lt;br /&gt;&lt;br /&gt;So over the weekend I installed Ubuntu 6.10 server which I later updated to 7.04 (linux kernel 2.6.20) via apt-get.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; lspci&lt;br /&gt;00:00.0 Host bridge: Broadcom GCNB-LE Host Bridge (rev 32)&lt;br /&gt;00:00.1 Host bridge: Broadcom GCNB-LE Host Bridge&lt;br /&gt;00:03.0 VGA compatible controller: ATI Technologies Inc Rage XL (rev 27)&lt;br /&gt;00:0f.0 ISA bridge: Broadcom CSB6 South Bridge (rev a0)&lt;br /&gt;00:0f.1 IDE interface: Broadcom CSB6 RAID/IDE Controller (rev a0)&lt;br /&gt;00:0f.2 USB Controller: Broadcom CSB6 OHCI USB Controller (rev 05)&lt;br /&gt;00:0f.3 Host bridge: Broadcom GCLE-2 Host Bridge&lt;br /&gt;00:10.0 Host bridge: Broadcom CIOB-E I/O Bridge with Gigabit Ethernet (rev 12)&lt;br /&gt;00:10.2 Host bridge: Broadcom CIOB-E I/O Bridge with Gigabit Ethernet (rev 12)&lt;br /&gt;&lt;font color="red"&gt;01:06.0 Ethernet controller: Atheros Communications, Inc. AR5005G 802.11abg NIC (rev 01)&lt;/font&gt;&lt;br /&gt;02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5704 Gigabit Ethernet (rev 02)&lt;br /&gt;02:00.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5704 Gigabit Ethernet (rev 02)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Setting this up with Ubuntu is tricky. I tried a few of the solutions and ended up updating the 6.10 to 7.04 in the process. I finally found this &lt;a href="http://www.stchman.com/ath_adrv.html"&gt;script&lt;/a&gt; which worked great and I was able to use my wireless interface as my primary network interface. If you need further instructions with setting this up, drop me a comment and I will try to help. &lt;br /&gt;&lt;font color="red"&gt;Note that the madwifi code needs to be patched eventually for vmware bridging to wireless NICs to work. See below.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Next up was the VMware server. I installed a couple of Ubuntu packages listed &lt;a href="http://users.piuha.net/martti/comp/ubuntu/server.html"&gt;here&lt;/a&gt; as dependencies for the server.&lt;br /&gt;&lt;br /&gt;I then tried to run the vmware-install.pl included in VMware-server-1.0.3-44356.tar.gz to install the VMware host. The script failed while trying to build vmmon.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;%&gt; cd vmware-server-distrib &lt;br /&gt;%&gt; sudo vmware-install.pl&lt;br /&gt;...&lt;br /&gt;Using 2.6.x kernel build system.&lt;br /&gt;make: Entering directory `/tmp/vmware-config0/vmmon-only'&lt;br /&gt;make -C /lib/modules/2.6.20-16-386/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules&lt;br /&gt;make[1]: Entering directory `/usr/src/linux-headers-2.6.20-16-386'&lt;br /&gt;  CC [M]  /tmp/vmware-config0/vmmon-only/linux/driver.o&lt;br /&gt;In file included from /tmp/vmware-config0/vmmon-only/linux/driver.c:80:&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: error: expected declaration specifiers or â...â before âcompat_exitâ&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: error: expected declaration specifiers or â...â before âexit_codeâ&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: warning: type defaults to âintâ in declaration of â_syscall1â&lt;br /&gt;make[2]: *** [/tmp/vmware-config0/vmmon-only/linux/driver.o] Error 1&lt;br /&gt;make[1]: *** [_module_/tmp/vmware-config0/vmmon-only] Error 2&lt;br /&gt;make[1]: Leaving directory `/usr/src/linux-headers-2.6.20-16-386'&lt;br /&gt;make: *** [vmmon.ko] Error 2&lt;br /&gt;make: Leaving directory `/tmp/vmware-config0/vmmon-only'&lt;br /&gt;Unable to build the vmmon module.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I used &lt;a href="http://www.howtoforge.com/ubuntu_feisty_fawn_vmware_server_howto"&gt;vmware-any-any-update fix&lt;/a&gt; to resolve this issue. &lt;br /&gt;&lt;font color="red"&gt;Later however I found that vmware-any-any update causes problems with madwifi patch to allow vmware bridging to wireless interfaces on the host. See below how to fix the vmmon compile problem.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="red"&gt;Note&lt;/font&gt;: &lt;span style="font-style:italic;"&gt;if you get vmware server is not configured message when you run vmware, simply delete the /etc/vmware/not_configured file and rerun vmware.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I set up the networking to bridge vmnet0 to ath0 (my Ubuntu server's wireless NIC). I skipped Host only and NAT portions.&lt;br /&gt;&lt;br /&gt;I happily bought up my CentOS development VM. But unfortunately the network didn't work. So it was back to googling. &lt;br /&gt;&lt;br /&gt;I saw various posts on how it worked for some people by changing /etc/vmware/locations file (make sure VNET_0_INTERFACE is set to  ath0), but my version of the file had it already set to that.&lt;br /&gt;&lt;br /&gt;Then I came across &lt;a href="http://ubuntuforums.org/showthread.php?t=285846"&gt;posts &lt;/a&gt;where folks had patched there madwifi drivers. Though my setup wasn't reporting the problem, I tried it anyways, but no dice.&lt;br /&gt;&lt;font color="red"&gt;Eventually I found that this patch works, but the vmware-any-any update seems to break it in some way.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Some posts claimed that since wireless frames are different than ethernet frames, the bridging of Guest-eth0 to Host-ath0 is not possible. Soon after I read that VMware server supports bridging to wireless NICs, but it just didn't work for me.&lt;br /&gt;&lt;br /&gt;Explored other approaches such as &lt;a href="http://www.emcken.dk/weblog/archives/156-Using-ath0-as-bridge-in-VMware...-or-almost.html"&gt;Host only networking&lt;/a&gt;, NAT etc to resolve the issue.  Spent a day in reading up on iptables. But couldn't figure out how to get a single network topology using my setup. If any networking experts could comment, I would really appreciate it.&lt;br /&gt;&lt;br /&gt;I jumped back to vmware bridge solutions and re-read the &lt;a href="http://madwifi.org/ticket/407"&gt;madwifi ticket&lt;/a&gt;. One user warned against installing vmware-any-any patches. So I completely cleaned up my vmware server install and performed the following steps:&lt;br /&gt;&lt;br /&gt;Solution Mix:&lt;br /&gt;Note: do this before installing vmware.&lt;br /&gt;&lt;br /&gt;1)  Apply the &lt;a href="http://madwifi.org/ticket/407"&gt;madwifi &lt;/a&gt;patch described by xgerligand@free.fr. make clean, make and make install and then reboot.&lt;br /&gt;&lt;br /&gt;2) Now untar vmware-server-distrib and apply the patch described &lt;a href="http://ubuntuforums.org/showthread.php?t=413646&amp;page=2"&gt;here &lt;/a&gt; by turn1200 to fix the vmmon problem that occurs when you run vmware-install.pl without using the vmware-any-any patch. Recording the commands here...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cd vmware-server-distrib/lib/modules/source/&lt;br /&gt;tar -xvf vmmon.tar&lt;br /&gt;vi vmmon-only/include/compat_kernel.h&lt;br /&gt;&lt;br /&gt;change the line that says:&lt;br /&gt;static inline _syscall1(int, compat_exit, int, exit_code);&lt;br /&gt;to the following by removing two commas:&lt;br /&gt;static inline _syscall1(int compat_exit, int exit_code);&lt;br /&gt;&lt;br /&gt;sudo tar -cvf vmmon.tar vmmon-only/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3) Now run sudo vmware-install.pl and vmware installation should complete successfully.&lt;br /&gt;&lt;br /&gt;Hopefully this will be of help to others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-491398719801805178?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/491398719801805178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=491398719801805178' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/491398719801805178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/491398719801805178'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/setting-up-ubuntu-704-feisty-as-vmware.html' title='Setting up Ubuntu 7.04 (Feisty) as  vmware host with a wireless card'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-1981766029995537155</id><published>2007-06-20T23:56:00.000-07:00</published><updated>2007-08-02T15:48:53.406-07:00</updated><title type='text'>ActiveDirectory (LDAP) integration with Rails</title><content type='html'>Updated:&lt;br /&gt;The &lt;a href="http://justbarebones.blogspot.com/2007/08/activedirectory-ldap-integration-with.html"&gt;solution&lt;/a&gt; that I went with. Read this article completely first so you are aware of the landscape.&lt;br /&gt;EOM&lt;br /&gt;&lt;br /&gt;I am currently exploring options to allow my rails apps to authenticate against an ActiveDirectory server. Active Directory is Windows 2000/2003 implementation of LDAP.&lt;br /&gt;&lt;br /&gt;This post rounds up the options available and is my brain dump on the topic:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Authentication built into Rails:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When you want to code in the authentication mechanism within the rails app itself, you can use one of the following modules. This may be of interest when the rails app needs to know more details about the user and user's group memberships etc for security purposes and restrict parts of the website depending on user.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Net:LDAP&lt;br /&gt;&lt;a href="http://wiki.rubyonrails.org/rails/pages/HowtoAuthenticateWithRubyNetLdap"&gt;Recommended&lt;/a&gt; on rails wiki since it is pure ruby and has no other external dependencies. There is some code on the rails wiki that allows one to derive groups the user belongs to. I haven't tried it.  &lt;/li&gt;&lt;li&gt;ruby/ldap&lt;br /&gt;This &lt;a href="http://blog.saush.com/?p=103"&gt;post&lt;/a&gt; describes using ruby/ldap to allows authentication against a AD server. It has sample code to get the groups a user is assigned to.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ActiveLDAP&lt;br /&gt;The rails wiki has more &lt;a href="http://wiki.rubyonrails.com/rails/pages/ActiveLDAP"&gt;info&lt;/a&gt;. Looks like ruby/ldap is recommended over this library.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Authentication done via Web Server:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;The idea here is to have the web server perform the authentication and only forward the request to the Rails app if the user is authenticated. The user info (username, groups) etc may be passed to the Rails app using HTTP variables or cgi params. I will write about this more later as I come to that step.&lt;br /&gt;&lt;br /&gt;A big reason why one may wish to use authentication done by the web server is to support single sign-on.  Microsoft IE (and &lt;a href="http://www.therightstuff.de/2006/04/28/Automatic+NTLM+Authentication+In+Firefox.aspx"&gt;firefox&lt;/a&gt;) allow the automatic authentication using the current Windows user information.   This is called I&lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/523ae943-5e6a-4200-9103-9808baa00157.mspx?mfr=true"&gt;ntegrated Windows Authentication&lt;/a&gt;, formerly called NTLM. However this requirement limits the web server that can be used as our front-end.&lt;br /&gt;&lt;br /&gt;Here is a list of possible combinations:&lt;br /&gt;Windows based&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IIS + Mongrel + ISAPI Rewrite - more info &lt;a href="http://www.napcsweb.com/howto/rails/deployment/railsonIISWithMongrel.pdf"&gt;here.&lt;/a&gt; The problem here is rails caching doesn't work with this setup.&lt;a href="http://www.napcsweb.com/howto/rails/deployment/railsonIISWithMongrel.pdf"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;IIS + Mongrel + lighttpd + Mongrel + ISAPI Rewrite - more info &lt;a href="http://www.napcsweb.com/howto/rails/deployment/railsonIISWithLighttpdAndMongrel.pdf"&gt;here&lt;/a&gt;. A better solution since static files and cached fragments can be served by the lighttpd quickly and faster.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Apache + SCGI + mod_auth_sspi - &lt;a href="http://www.zorched.net/2007/06/04/active-directory-authentication-for-ruby-on-rails/trackback/"&gt;here&lt;/a&gt; . mod_auth_sspi adds NTLM/LDAP authentication to apache.&lt;br /&gt;However it is not known if it supports groups.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Linux&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Apache + &lt;a href="http://www.muquit.com/muquit/software/mod_auth_ldap/mod_auth_ldap.html"&gt;mod_auth_ldap&lt;/a&gt; + &lt;a href="http://modntlm.sourceforge.net/"&gt;mod_ntlm&lt;/a&gt; - reported to be sorta unstable.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Hybrid&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IIS + ISAPI Rewrite on Windows, proxying http requests to a lighttpd + Mongrel setup on a Linux box.&lt;br /&gt;This seems to be the ideal  solution.  The Lighttpd + Mongrel cluster is a proven setup and can be scaled by simply adding more rails instances. lighttpd can easily load balance these rails clusters. And static and cached fragments can be served quickly by the lighttpd.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;More to come.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-1981766029995537155?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/1981766029995537155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=1981766029995537155' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1981766029995537155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/1981766029995537155'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/activedirectory-ldap-integration-with.html' title='ActiveDirectory (LDAP) integration with Rails'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-6236956556122741275</id><published>2007-06-14T20:42:00.000-07:00</published><updated>2007-06-14T21:52:04.439-07:00</updated><title type='text'>Rails -  render :action vs render :template</title><content type='html'>&lt;span style="color: rgb(204, 102, 0);font-size:180%;" &gt;&lt;span style="color: rgb(153, 0, 0);"&gt;render :action     vs      render :template&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;One can use render :action to render the template associated with another action.&lt;br /&gt;&lt;br /&gt;However, when the user does&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def action1&lt;br /&gt;   @foo = "action1"&lt;br /&gt;   render :action =&gt; "action2"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def action2&lt;br /&gt;  @foo = "action2"&lt;br /&gt;   render&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the user should realize the method associated with action2 is not exectued when action1 calls render :action =&gt; "action2". This is simply the equivalent of render :template =&gt; "my_controller/action2".&lt;br /&gt;&lt;br /&gt;This can get confusing when action2 in turn uses a non-default template to render itself.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def action1&lt;br /&gt;   @foo = "action1"&lt;br /&gt;   render :action =&gt; "action2"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def action2&lt;br /&gt;  @foo = "action2"&lt;br /&gt;   render  :template =&gt; "some/other"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this case, when action1 is executed, rails will return an error complaining "views/my_controller/action2.rhtml" was not found.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-6236956556122741275?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/6236956556122741275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=6236956556122741275' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6236956556122741275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/6236956556122741275'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/rails-render-action-vs-render-template.html' title='Rails -  render :action vs render :template'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-7935687926461017669</id><published>2007-06-13T17:18:00.000-07:00</published><updated>2007-06-14T10:51:12.676-07:00</updated><title type='text'>Rails scripts/breakpointer questions</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;NOTES:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Things of interest : &lt;code id="l6_39"&gt;local_variables&lt;/code&gt;, &lt;code id="l6_40"&gt;instance_variables&lt;/code&gt;, &lt;code id="l6_41"&gt;caller&lt;/code&gt;, &lt;code id="l6_42"&gt;methods&lt;/code&gt;&lt;span style="font-family: monospace;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: monospace;"&gt;&lt;/span&gt;Keep a close eye on the prompt. A &lt;span style="font-weight: bold;"&gt;*&lt;/span&gt; means breakpointer (irb really) expects you to enter more ruby code since it senses that the code entered so far is not fully valid yet.&lt;/li&gt;&lt;li&gt;breakpointer (irb really) will by default print the return value to the irb console. You can explicitly return false to disable printing of large datasets.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpointer&gt; @copy = @huge_dataset; false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For regular irb (and script/console)  &lt;a href="http://austinruby.com/2006/10/6/quieting-irb-s-return-value"&gt;setting conf.return_format&lt;/a&gt; allows you to limit what is printed, but conf object doesn't seem to exist in breakpointer's irb session.&lt;/li&gt;&lt;/ol&gt;&lt;code id="l6_42"&gt;&lt;br /&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(153, 0, 0); font-style: italic;font-size:130%;" &gt;How do you print out variable values?&lt;/span&gt;&lt;br /&gt;puts doesn't work :)  &lt;span style="color: rgb(255, 0, 0);"&gt;Update&lt;/span&gt;: It actually prints the output along with the script/server output.&lt;br /&gt;&lt;br /&gt;You can use @logger.info etc which will print the info to development.log&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(153, 51, 0);font-size:130%;" &gt;Local variables&lt;/span&gt;&lt;span style="font-style: italic; color: rgb(153, 51, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt; &lt;/span&gt;&lt;br /&gt;I put a breakpoint in a helper method and tried to view some local variables defined in the helper method, but it didn't work.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpoint&gt; local_variables&lt;br /&gt;=&gt; ["id", "block", "_"]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(note that I cleaned the irb prompt and replaced it with breakpoint for blogging)&lt;br /&gt;The reason is breakpoint drops me in the breakpoint.rb's breakpoint method.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpoint&gt; caller&lt;br /&gt;=&gt; ["/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/breakpoint.rb:512:in `breakpoint'", "/usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/breakpoint.rb:512:in `breakpoint'", "script/../...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now to figure out how we pop the stack back up so we end up in the method.  Anyone know?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic; color: rgb(51, 51, 255);"&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;Printing Huge datasets&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Suppose I am debugging some calculations I am doing on a hude dataset in breakpointer:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpoint&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;@huge_dataset&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will print the entire dataset. Ctrl-C will stop the display.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpoint&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;@huge_dataset;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This doesn't print the dataset.&lt;br /&gt;&lt;br /&gt;So how is one to print the dataset. One solution is to use &lt;span style="font-weight: bold; font-style: italic;"&gt;to_yaml&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;breakpoint&gt;  fh = File.open("/tmp/foo", "w");&lt;br /&gt;breakpoint&gt;  fh.puts(@huge_dataset.to_yaml)&lt;br /&gt;=&gt; nil&lt;br /&gt;breakpoint&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I would really like to print the value in the breakpointer's irb console though.&lt;br /&gt;Is there a special console object that I can target?&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Update&lt;/span&gt;: Another way to debug your rails app -&lt;a href="http://isaac.org.nz/2007/2/17/ruby-debug"&gt; ruby-debug&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-7935687926461017669?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/7935687926461017669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=7935687926461017669' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7935687926461017669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/7935687926461017669'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/rails-scriptsbreakpointer-questions.html' title='Rails scripts/breakpointer questions'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8718987133035399176</id><published>2007-06-13T16:46:00.000-07:00</published><updated>2007-06-14T10:51:55.678-07:00</updated><title type='text'>Rails script/console questions</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic; color: rgb(153, 51, 0);"&gt;How to invoke a method defined in a helper module in script/console?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic; color: rgb(153, 51, 0);font-size:130%;" &gt;How to get the list of classes loaded by underlying irb in script/console?&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8718987133035399176?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8718987133035399176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8718987133035399176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8718987133035399176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8718987133035399176'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/rails-scriptconsole-questions.html' title='Rails script/console questions'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8878605820975597136</id><published>2007-06-11T14:58:00.000-07:00</published><updated>2007-06-11T15:08:25.573-07:00</updated><title type='text'>Extending Tcl's package include directories at run-time</title><content type='html'>A quick one here:&lt;br /&gt;Say you are debugging a tcl package and have a local copy to debug.&lt;br /&gt;&lt;br /&gt;To make the tcl script pick up the local copy  of the package:&lt;br /&gt;&lt;br /&gt;- If the tcl script is editable, append to  auto_path as&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;set auto_path "./src $::auto_path"&lt;br /&gt;package require Foo&lt;br /&gt;&lt;/pre&gt;Note that you would need to create a &lt;i&gt;pkgIndex.tcl &lt;/i&gt;in the directory where your local copy exists.&lt;br /&gt;&lt;br /&gt;- If the tcl script is not-editable, use TCLLIBPATH env var. Haven't tried it though.&lt;br /&gt;&lt;br /&gt;o&amp;amp;o&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8878605820975597136?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8878605820975597136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8878605820975597136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8878605820975597136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8878605820975597136'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/06/extending-tcls-package-include.html' title='Extending Tcl&apos;s package include directories at run-time'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-8518620785386673193</id><published>2007-05-17T15:49:00.000-07:00</published><updated>2007-05-17T16:22:48.592-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='variable interpolation'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Perl - Variable Interpolation for single quoted strings</title><content type='html'>A colleague was writing a perl script to print a string with embedded newlines in it. The string originated as a multi-line environment variable value i.e.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;csh%&gt;   setenv Foo "a b c\nd e f"&lt;br /&gt;csh %&gt;  echo $Foo&lt;br /&gt;a b c&lt;br /&gt;d e f&lt;br /&gt;csh %&gt;&lt;br /&gt;&lt;br /&gt;csh %&gt; perl -e 'print $ENV{Foo} . "\n";'&lt;br /&gt;a b c\nd e f&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The value of $ENV{Foo} was being interpreted as a singly quoted string and the \n was being automatically backslashed internally whenever variable interpolation took place.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;index($ENV{Foo}, '\n') ;  #  returned 5&lt;br /&gt;index($ENV{Foo}, "\\n") ;  #  returned 5&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There are a couple of ways to solve this&lt;br /&gt;&lt;code&gt;&lt;br /&gt;% perl -e '$ENV{Foo} =~ s/\\n/\n/g; print $ENV{Foo} . "\n";'&lt;br /&gt;or&lt;br /&gt;% perl -e 'eval "\$f = \"" . $ENV{Foo} . "\""; print $f . "\n";'&lt;br /&gt;  ( or in a script  use: eval '$f = "'. $ENV{Foo} . '"'; )&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I was hoping there are better ways to do this. The first solution uses the regular expression engine to match every character in the string with the pattern. The second solution uses eval!&lt;br /&gt;&lt;br /&gt;Is there a perl hack that will force variable interpolation on a singly quoted string?  I thought of unpack but didn't have enough time to look into it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-8518620785386673193?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/8518620785386673193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=8518620785386673193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8518620785386673193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/8518620785386673193'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/05/perl-variable-interpolation-for-single.html' title='Perl - Variable Interpolation for single quoted strings'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7096286173817193675.post-3947013234860503412</id><published>2007-05-15T16:31:00.000-07:00</published><updated>2007-06-14T21:53:50.628-07:00</updated><title type='text'>First Post</title><content type='html'>Hey there!&lt;br /&gt;Welcome to my blog.&lt;br /&gt;I plan on posting tech stuff like Javascript, ROR, HTML, CSS, Perl/Tcl and stuff that interests me!&lt;br /&gt;&lt;br /&gt;So stick around if this interests you!&lt;br /&gt;&lt;br /&gt;BTW, this is sort of continuation from http://rail101.blogspot.com.&lt;br /&gt;In the transition to Google, blogger.com  somehow mucked my account. I am unable to access all my earlier blogs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7096286173817193675-3947013234860503412?l=justbarebones.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://justbarebones.blogspot.com/feeds/3947013234860503412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7096286173817193675&amp;postID=3947013234860503412' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3947013234860503412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7096286173817193675/posts/default/3947013234860503412'/><link rel='alternate' type='text/html' href='http://justbarebones.blogspot.com/2007/05/first-post.html' title='First Post'/><author><name>-</name><uri>http://www.blogger.com/profile/12767133399409331298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
