<?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'><id>tag:blogger.com,1999:blog-2081540614849175978</id><updated>2009-10-13T17:41:25.935-07:00</updated><title type='text'>From Java To Ruby</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-7164712426094304533</id><published>2008-11-09T18:07:00.000-08:00</published><updated>2008-11-09T18:36:27.696-08:00</updated><title type='text'>Hpricot for XML parsing</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_YIdH0N1C-og/SRedvSOyS9I/AAAAAAAAAAY/qYPquK-DiJI/s1600-h/Picture+5.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 196px;" src="http://1.bp.blogspot.com/_YIdH0N1C-og/SRedvSOyS9I/AAAAAAAAAAY/qYPquK-DiJI/s320/Picture+5.png" alt="" id="BLOGGER_PHOTO_ID_5266851724906351570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Hpricot is flexible and fast html/xml parser.&lt;br /&gt;To install:&lt;br /&gt;$ sudo gem install hpricot&lt;br /&gt;&lt;br /&gt;require 'hpricot'&lt;br /&gt;&lt;br /&gt;doc = Hpricot(xml_string)&lt;br /&gt;doc.search("/rows/row").each do |row|&lt;br /&gt;    group_and_row_id = row.get_attribute("id")&lt;br /&gt;    row.search("/cell").each do |cell|   &lt;br /&gt;        cell_text = cell.html&lt;br /&gt;    end&lt;br /&gt;end&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-7164712426094304533?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/7164712426094304533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=7164712426094304533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7164712426094304533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7164712426094304533'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/11/hpricot-for-xml-parsing.html' title='Hpricot for XML parsing'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_YIdH0N1C-og/SRedvSOyS9I/AAAAAAAAAAY/qYPquK-DiJI/s72-c/Picture+5.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-911047032302664138</id><published>2008-11-09T17:54:00.000-08:00</published><updated>2008-11-09T18:03:14.125-08:00</updated><title type='text'>Caution with String concat &lt;&lt;</title><content type='html'>If you have a string  a = "test" and you want to append dynamic data, be careful with &lt;&lt;/concat method&lt;br /&gt;If the dynamic data happens to be a Fixnum between 0 and 255, it is converted to a character before concatenation.&lt;br /&gt;&lt;br /&gt;&gt;&gt; a = "test"&lt;br /&gt;=&gt; "test"&lt;br /&gt;&gt;&gt; a &lt;&lt; 12&lt;br /&gt;=&gt; "test\f"&lt;br /&gt;&gt;&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-911047032302664138?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/911047032302664138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=911047032302664138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/911047032302664138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/911047032302664138'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/11/caution-with-string-concat.html' title='Caution with String concat &lt;&lt;'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-2745402610817710806</id><published>2008-11-09T17:41:00.000-08:00</published><updated>2008-11-09T17:54:06.202-08:00</updated><title type='text'>dhtmlxGrid in a Rails App</title><content type='html'>Here is my experience using dhtmlxGrid in ROR app.&lt;br /&gt;In general, it is a nice component and comes with lots of sample code. Their support and knowledge is good. Their document list json as supported data type but json support is a subset of XML type.  Even if you load the grind in JSON, when you serialize the grid, you get xml back and cell id is not sent back. In rails project, to generate xml, when you use xml builder, make sure, you don't indent. Grid dosn't load xml string with indentation.&lt;br /&gt; Use Builder::XmlMarkup.new (no indent)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-2745402610817710806?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/2745402610817710806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=2745402610817710806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2745402610817710806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2745402610817710806'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/11/dhtmlxgrid-in-rails-app.html' title='dhtmlxGrid in a Rails App'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-7326807177339276165</id><published>2008-11-09T17:34:00.000-08:00</published><updated>2008-11-09T17:41:01.571-08:00</updated><title type='text'>Don't use column name type</title><content type='html'>I had a table and there was a business need to add a type column in the table. Adding a type column as an integer or as an string didn't work.&lt;br /&gt;"type" is a reserved field name for single table inheritance (STI). Active Record allows inheritance by storing the name of the class in a column that by default is called “type”&lt;br /&gt;&lt;br /&gt;Here are the magic field names in Rails:&lt;br /&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/MagicFieldNames"&gt;http://wiki.rubyonrails.com/rails/pages/MagicFieldNames&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-7326807177339276165?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/7326807177339276165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=7326807177339276165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7326807177339276165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7326807177339276165'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/11/dont-use-column-name-type.html' title='Don&apos;t use column name type'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-8175653932288078854</id><published>2008-11-09T17:09:00.000-08:00</published><updated>2008-11-09T17:30:25.662-08:00</updated><title type='text'>HowtoGenerateJSON</title><content type='html'>Recently, I needed JSON format to load data in dhtml component. It was trivial. I installed ruby-json gem. In my model class, I had to do the following:&lt;br /&gt;&lt;br /&gt;require 'json/objects'&lt;br /&gt;&lt;br /&gt;  def to_json&lt;br /&gt;    result = Hash.new&lt;br /&gt;    rows = []&lt;br /&gt;    qg_rows = all_records&lt;br /&gt;   &lt;br /&gt;    qg_rows.each_with_index do |row_data|&lt;br /&gt;      row = {}&lt;br /&gt;      data = []   &lt;br /&gt;      row_data.each  {|cells|       &lt;br /&gt;        ------&lt;br /&gt;        data &lt;&lt; cell_data&lt;br /&gt;      }&lt;br /&gt;      row [:data] = data&lt;br /&gt;      rows &lt;&lt; row&lt;br /&gt;    end&lt;br /&gt;    result[:rows] = rows&lt;br /&gt;    result.to_json&lt;br /&gt;&lt;br /&gt;  end&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-8175653932288078854?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/8175653932288078854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=8175653932288078854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8175653932288078854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8175653932288078854'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/11/howtogeneratejson.html' title='HowtoGenerateJSON'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-8322562705794892010</id><published>2008-10-11T10:40:00.000-07:00</published><updated>2008-10-11T10:50:44.461-07:00</updated><title type='text'>escaping javascript</title><content type='html'>Javascript provides&lt;br /&gt;&lt;pre&gt;escape(string)&lt;/pre&gt; method but it does not escapes the following chars:&lt;br /&gt;* @ - _ + . /&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Use encodeURIComponent(URIstring)instead. The encodeURIComponent method encodes all characters.&lt;/pre&gt;Use the decodeURIComponent() function to decode URIs encoded  with encodeURIComponent().&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-8322562705794892010?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/8322562705794892010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=8322562705794892010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8322562705794892010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8322562705794892010'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/10/escaping-javascript.html' title='escaping javascript'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-4358415393188698424</id><published>2008-10-10T05:47:00.000-07:00</published><updated>2008-10-10T05:55:52.424-07:00</updated><title type='text'>URI escaping</title><content type='html'>Which one to use? URI.escape or CGI.escape? Lets look at irb:&lt;br /&gt;&gt;&gt; URI.escape('Test &lt;&gt;?/&amp;amp;;=:.')&lt;br /&gt;=&gt; "Test%20%3C%3E?/&amp;amp;;=:."&lt;br /&gt;&gt;&gt; CGI.escape('Test &lt;&gt;?/&amp;amp;;=:.')&lt;br /&gt;=&gt; "Test+%3C%3E%3F%2F%26%3B%3D%3A."&lt;br /&gt;&lt;br /&gt;CGI.escape is looking better but it does not escape dots which gives "RoutingError No route matches". Here is the solution working for me&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;&gt;&gt; test = URI.escape(CGI.escape('Test &lt;&gt;?/&amp;amp;;=:.'),'.')&lt;/span&gt;&lt;br /&gt;=&gt; "Test+%3C%3E%3F%2F%26%3B%3D%3A%2E"&lt;br /&gt;&gt;&gt; CGI.unescape(test)&lt;br /&gt;=&gt; "Test &lt;&gt;?/&amp;amp;;=:."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-4358415393188698424?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/4358415393188698424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=4358415393188698424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/4358415393188698424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/4358415393188698424'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/10/uri-escaping.html' title='URI escaping'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-8799842798158972989</id><published>2008-10-05T17:08:00.000-07:00</published><updated>2008-10-05T17:32:33.860-07:00</updated><title type='text'>Formatting phone numbers, Fax numbers</title><content type='html'>I created a plug-in act_as_formatted to format numbers, phone/fax  numbers and zip codes.  If there is number field (stored as integer in DB) and user formats it using "," for example 10,010, this gets saved as 10 (without special handling). To solve this problem I created a plug-in act_as_formatted. This plug-in creates *_ui and *_ui= methods on ActiveRecord models. attrubute_ui does the formatting and attribute_ui= ensures, right data is being saved. Example usage:&lt;br /&gt;In model&lt;br /&gt;acts_as_number :revenue&lt;br /&gt;acts_phone_number :phone&lt;br /&gt; In view use attribute_ui&lt;br /&gt;&lt;%= company.revenue_ui %&gt;&lt;br /&gt;&lt;%= company.phone_ui %&gt;&lt;br /&gt;---------------------------------------&lt;br /&gt;Here is the code. Ideally model should not be using ActionView::Helpers::NumberHelper but for now this seems to be working fine for e.&lt;br /&gt;&lt;br /&gt;class ActiveRecord::Base&lt;br /&gt;include ActionView::Helpers::NumberHelper&lt;br /&gt;include ERB::Util&lt;br /&gt; &lt;br /&gt;  def self.format_as_number(*args)&lt;br /&gt;&lt;br /&gt;    args.each do |arg|&lt;br /&gt;   &lt;br /&gt;      define_method "#{arg.to_s}_ui=" do |number_string|&lt;br /&gt;          if number_string&lt;br /&gt;          # If a valid number, sanitize to digits only&lt;br /&gt;            if valid_number? number_string&lt;br /&gt;                number_string.gsub!(/[^0-9]/, "")&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;          write_attribute(arg, number_string)     &lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;   &lt;br /&gt;    args.each do |arg|&lt;br /&gt;      define_method "#{arg.to_s}_ui"  do&lt;br /&gt;          val = read_attribute(arg)&lt;br /&gt;          begin&lt;br /&gt;            number_with_delimiter val if val&lt;br /&gt;          rescue&lt;br /&gt;            val&lt;br /&gt;          end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;   &lt;br /&gt;    define_method 'validate' do&lt;br /&gt;       args.each { |arg|&lt;br /&gt;         error_message = 'is invalid. It can contain only digits'&lt;br /&gt;         if !eval(arg.to_s).nil?           &lt;br /&gt;           errors.add(arg, error_message) unless valid_number? eval(arg.to_s)          &lt;br /&gt;         end&lt;br /&gt;       }&lt;br /&gt;     end   &lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.format_as_phone_number(*args)&lt;br /&gt;   &lt;br /&gt;    args.each do |arg|&lt;br /&gt;   &lt;br /&gt;      define_method "#{arg.to_s}=" do |number_string|&lt;br /&gt;        if number_string&lt;br /&gt;          # If a valid phone number(can contain only  0-9/-()+xX),&lt;br /&gt;          # sanitize it to "digits only" only if 10 digits long&lt;br /&gt;          # If number has more that 10 digits, store it as is&lt;br /&gt;           if valid_phone? number_string&lt;br /&gt;            numbers = number_string.gsub(/[^0-9]/, "")&lt;br /&gt;            if numbers.size == 10&lt;br /&gt;              number_string = numbers&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;        end&lt;br /&gt;        write_attribute(arg, number_string)&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;   &lt;br /&gt;    args.each do |arg|&lt;br /&gt;      define_method "#{arg.to_s}_ui"  do&lt;br /&gt;          val = read_attribute(arg)&lt;br /&gt;          begin&lt;br /&gt;            if val&lt;br /&gt;              numbers = val.gsub(/[^0-9]/, "")&lt;br /&gt;              #Format 10 digits phone number only             &lt;br /&gt;              if numbers.size == 10&lt;br /&gt;                return number_to_phone(numbers,:area_code =&gt; true)&lt;br /&gt;              end&lt;br /&gt;            end       &lt;br /&gt;            val&lt;br /&gt;          rescue&lt;br /&gt;            val&lt;br /&gt;          end        &lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;   &lt;br /&gt;    define_method 'validate' do&lt;br /&gt;       args.each { |arg|&lt;br /&gt;         error_message = 'is invalid. It must contain at least 5 digits, only the following characters are allowed: 0-9/-()+x'&lt;br /&gt;         if !eval(arg.to_s).nil?           &lt;br /&gt;           errors.add(arg, error_message) unless valid_phone? eval(arg.to_s)          &lt;br /&gt;         end&lt;br /&gt;       }&lt;br /&gt;     end   &lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;# Valid phone number can contain only  0-9/-()+xX and whitespace.&lt;br /&gt;  def valid_phone?(number)&lt;br /&gt;    return true if( number.nil? || number.strip.size == 0)&lt;br /&gt;    n_digits = number.scan(/[0-9]/).size&lt;br /&gt;    valid_chars = (number =~ /^[xX.+\/\-() 0-9]+$/)&lt;br /&gt;    return n_digits &gt;= 5 &amp;amp;&amp;amp; valid_chars&lt;br /&gt;  end &lt;br /&gt; &lt;br /&gt; # Valid number can contain only digits and ,.&lt;br /&gt; def valid_number?(number)&lt;br /&gt;      return true if( number.nil? || number.strip.size == 0)&lt;br /&gt;      valid_chars = (number =~ /^[\,\ 0-9]+$/)&lt;br /&gt;      return valid_chars&lt;br /&gt;    end &lt;br /&gt; &lt;br /&gt;end&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-8799842798158972989?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/8799842798158972989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=8799842798158972989' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8799842798158972989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8799842798158972989'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/10/formatting-phone-numbers-fax-numbers.html' title='Formatting phone numbers, Fax numbers'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-2979560144758123198</id><published>2008-10-04T16:44:00.000-07:00</published><updated>2008-10-04T17:22:28.417-07:00</updated><title type='text'>Protecting app from Cross Site Scripting</title><content type='html'>&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;RoR provides methods for escaping metacharacters. To HTML escape data in RoR simply add an "h" inside your output tag.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;It is hard to remember using this everywhere. &lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;There are several plug-in available which you can install and forget about adding "h". I tried &lt;a href="http://rubyforge.org/frs/group_id=1369&amp;amp;release_id=4329"&gt;auto_escape&lt;/a&gt; plug-in. This modifies ActiveRecord and and automatically applies CGI.escapeHTML to all text column. The plug-in works by defining an after_find call_back from ActiveRecord. Whenever a record is found and loaded from DB, this escapes text columns. Plug-in worked great but it slowed down the APP.&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;a href="http://xssterminate.googlecode.com/svn/trunk/xss_terminate"&gt;xss_terminate&lt;/a&gt; plug-in makes stripping and sanitizing HTML automatic. Install the plug-in and forget about h() because you don't need to. This plug-in makes use of before_save hook and strips HTML tags. Generally there are more read operations than save, so performance wise this plug-in worked better for my case.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-2979560144758123198?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/2979560144758123198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=2979560144758123198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2979560144758123198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2979560144758123198'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/10/protecting-app-from-cross-site.html' title='Protecting app from Cross Site Scripting'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-8543925434123068899</id><published>2008-07-15T17:22:00.000-07:00</published><updated>2008-07-19T15:00:40.551-07:00</updated><title type='text'>Textfield with auto complete</title><content type='html'>I wanted to add auto complete feature in a form field. I used auto_complete plug-in. It is a great plug-in, very simple to use. In few lines of code, I was able to get this up and running.&lt;br /&gt;&lt;br /&gt;1) To install run script/plugin install auto_complete&lt;br /&gt;2) In controller, add auto_complete_for :tag, :name where Tag is a model and name is a field, I wanted my auto complete on.&lt;br /&gt;3) In view add &lt;%= text_field_with_auto_complete :tag, :name %&gt;. The method it implements will search through all the Tags in you records database and do a LIKE comparison on the name column, comparing the name to the contents of the tag[title] form field.&lt;br /&gt;4) I had to reopen auto_plug to fix "Mysql::Error: #23000Column 'name' in where clause is ambiguous". In my case, for auto_complete_for method I was passing :joins condition.&lt;br /&gt;I wanted to show tags for a given model. Both Tag and Model had same column name "name".  To fix the problem, I created another plug_in name auto_complete_extended with single class init.rb. In init.rb I reopened auto_complete_for method (as follows):&lt;br /&gt;&lt;br /&gt;class ActionController::Base&lt;br /&gt;  # Reopening auto_complete_for from auto_complete plug-in&lt;br /&gt;   ### This is copy of auto_complete_for except for the part in condition where it qualifies column name with table name.&lt;br /&gt;  &lt;br /&gt;    def self.auto_complete_for(object, method, options = {})&lt;br /&gt;    define_method("auto_complete_for_#{object}_#{method}") do&lt;br /&gt;      find_options = {&lt;br /&gt;        :conditions =&gt; [ "LOWER(#{object.to_s.pluralize}.#{method}) LIKE ?", '%' + params[object][method].downcase + '%' ],&lt;br /&gt;        :order =&gt; "#{method} ASC",&lt;br /&gt;        :limit =&gt; 10 }.merge!(options)&lt;br /&gt;     &lt;br /&gt;      @items = object.to_s.camelize.constantize.find(:all, find_options)&lt;br /&gt;&lt;br /&gt;      render :inline =&gt; "&lt;%= auto_complete_result @items, '#{method}' %&gt;"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Thanks to for the following post. It helped me get started. &lt;a href="http://codeintensity.blogspot.com/2008/02/auto-complete-text-fields-in-rails-2.html"&gt;http://codeintensity.blogspot.com/2008/02/auto-complete-text-fields-in-rails-2.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-8543925434123068899?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/8543925434123068899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=8543925434123068899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8543925434123068899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/8543925434123068899'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/07/textfield-with-auto-complete.html' title='Textfield with auto complete'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-2181519655064781571</id><published>2008-06-23T18:17:00.000-07:00</published><updated>2008-06-24T19:01:31.552-07:00</updated><title type='text'>File upload with attachment_fu</title><content type='html'>Attachment_fu is a great plug-in to upload a file. I used Mike Clark's &lt;a href="http://clarkware.com/cgi/blosxom/2007/02/24"&gt;blog&lt;/a&gt; as an example. By default, it gives the following validation message:&lt;br /&gt;Content type can’t be blank&lt;br /&gt;Content type is not included in the list&lt;br /&gt;Size can’t be blank&lt;br /&gt;Size is not included in the list&lt;br /&gt;Filename can’t be blank&lt;br /&gt;&lt;br /&gt;To get better validation message, either reopen attachment_fu.rb or do your own validation in your model. The following &lt;a href="http://the.railsi.st/2007/11/27/roll-your-own-attachment_fu-validations"&gt;blog&lt;/a&gt; explains it nicely.&lt;br /&gt;&lt;br /&gt;If you are using MySQL, you may want to increase max_allowed_packet size in “my.cnf”.  The default size is apparently &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/packet-too-large.html" title="default max_allowed_packet size reference"&gt;1M&lt;/a&gt;. If you don't change this and upload a file larger than 1 M, you will get “ActiveRecord::StatementInvalid: Mysql::Error: #08S01Got a packet bigger than ‘max_allowed_packet’ bytes: INSERT INTO...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-2181519655064781571?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/2181519655064781571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=2181519655064781571' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2181519655064781571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/2181519655064781571'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/06/file-upload-with-attachmentfu.html' title='File upload with attachment_fu'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-75219753931817058</id><published>2008-06-22T12:45:00.000-07:00</published><updated>2008-06-22T13:21:44.581-07:00</updated><title type='text'>WYSIWYG-editor on Rails</title><content type='html'>I found the following post very helping &lt;a href="http://http://public.ok2life.com/welcome/index/48"&gt;http://public.ok2life.com/welcome/index/48&lt;/a&gt; and &lt;a href="http://public.ok2life.com/welcome/index/49.html"&gt;http://public.ok2life.com/welcome/index/49.html&lt;/a&gt; and &lt;a href="http://www.fckeditor.net/demo"&gt;http://www.fckeditor.net/demo&lt;/a&gt;. We are using FCKEditor and so far it is going very smoothly. In order to add a custom toolbar option, you need to write a plugin to fckeditor. In order to make spell checker to work, you need to install aspell &lt;a href="http://wiki.lyx.org/Mac/MacSpelling"&gt;http://wiki.lyx.org/Mac/MacSpelling&lt;/a&gt; and include file ActionView::Helpers::SanitizeHelper. I added the following line application's initializers dir&lt;br /&gt;include ActionView::Helpers::SanitizeHelper&lt;br /&gt; This was needed in Fckeditor: Version 0.4.3.&lt;br /&gt;&lt;br /&gt;To write a plug-in to fckeditor, follow direction on &lt;a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins"&gt;http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins&lt;/a&gt;. After reading documentation from this link, I used the following plugin as an example (note: fckeditor comes with this plug-in): /fckeditor/public/javascripts/fckeditor/editor/plugins/placeholder/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-75219753931817058?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/75219753931817058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=75219753931817058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/75219753931817058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/75219753931817058'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/06/wysiwyg-editor-on-rails.html' title='WYSIWYG-editor on Rails'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-3968925312047180752</id><published>2008-06-22T12:25:00.000-07:00</published><updated>2008-06-22T12:45:14.104-07:00</updated><title type='text'>Graph/Charts</title><content type='html'>For charts on rails, I looked GRUFF and OpenFlash. Open flash is very easy to use and provides more configuration options. You can get more information on open_flash_chart plug-in  from the following &lt;a href="http://teethgrinder.co.uk/open-flash-chart/"&gt;http://teethgrinder.co.uk/open-flash-chart  &lt;/a&gt;. I had to reopen Graph from open_flash_chart library, and redefine some methods to make look and feel changes.&lt;br /&gt;Sample:&lt;br /&gt;&lt;br /&gt;#Redefining method pie(alpha, line_color, style, gradient = true, border_size = false)&lt;br /&gt;# Original method had bug where it won't let you drop gradient&lt;br /&gt;  def pie(alpha, line_color, style, gradient = true, border_size = false)&lt;br /&gt;    @pie = "#{alpha},#{line_color},#{style}"&lt;br /&gt;    if !gradient&lt;br /&gt;      #@pie += ",#{!gradient}" # This is bug and won't drop gradient color&lt;br /&gt;      @pie += ",#{gradient}"&lt;br /&gt;    end&lt;br /&gt;    if border_size&lt;br /&gt;      @pie += "," if gradient === false&lt;br /&gt;      @pie += ",#{border_size}"&lt;br /&gt;    end&lt;br /&gt;  end &lt;br /&gt; &lt;br /&gt;  # Original Graph class is not exposing grid color setters.&lt;br /&gt;  def set_grid_color( color = '')&lt;br /&gt;    @x_grid_color = color&lt;br /&gt;    @y_axis_color  = color&lt;br /&gt;    @x_axis_color = color&lt;br /&gt;    @x_grid_color  = color&lt;br /&gt;    @y_grid_color = color&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://teethgrinder.co.uk/open-flash-chart/"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-3968925312047180752?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/3968925312047180752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=3968925312047180752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/3968925312047180752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/3968925312047180752'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/06/graphcharts.html' title='Graph/Charts'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-7212484624821660928</id><published>2008-06-22T11:00:00.000-07:00</published><updated>2008-06-22T12:24:52.815-07:00</updated><title type='text'>Ruby/Rails IDE</title><content type='html'>TextMate is the editor of choice for most folks on Mac but I am from Java and Windows. I missed rich IDE like features in TextMate. Most of all I missed nice debugging support. I evaluated Netbeans(6.1 RC2) and Aptana Studio(Eclipse based: build: 1.1.6.009905). I liked Aptana. Netbeans had very basic debugging support. Aptana debugging is richer. I tried using TextMate for a week too. In my opinion, if you are comfortable with Eclipse IDE, and if you use Aptana, you are not missing any thing big from TextMate. Here are more resources:&lt;br /&gt;&lt;a href="http://aptana.com/rails"&gt;http://aptana.com/rails&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tnlessone.wordpress.com/2007/02/28/ruby-rails-ide-comparison-idea-netbeans-radrails/"&gt;http://tnlessone.wordpress.com/2007/02/28/ruby-rails-ide-comparison-idea-netbeans-radrails/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-7212484624821660928?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/7212484624821660928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=7212484624821660928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7212484624821660928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/7212484624821660928'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/06/ruby-ide.html' title='Ruby/Rails IDE'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2081540614849175978.post-3506275203027534143</id><published>2008-06-22T10:35:00.000-07:00</published><updated>2008-06-22T10:56:13.704-07:00</updated><title type='text'>Books needed to get you started</title><content type='html'>&lt;a href="http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1214156205&amp;amp;sr=1-1"&gt;&lt;span class="srTitle"&gt;Ruby for Rails: Ruby Techniques for Rails Developers&lt;/span&gt;&lt;/a&gt;      by David Black is the best beginner book for learning ruby. This book gives you very good base on Ruby. I tried reading &lt;i&gt;Programming Ruby: The Pragmatic Programmer's Guide &lt;/i&gt;as 1st book but it didn't go that well. After reading Ruby for Rails, I read  Agile Web Development with Rails, 3rd Edition. This will get you started with Ruby and Rails. The Ruby Way and The Rails Way are good reference books .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2081540614849175978-3506275203027534143?l=rashmipandit.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rashmipandit.blogspot.com/feeds/3506275203027534143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2081540614849175978&amp;postID=3506275203027534143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/3506275203027534143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2081540614849175978/posts/default/3506275203027534143'/><link rel='alternate' type='text/html' href='http://rashmipandit.blogspot.com/2008/06/books-needed-to-get-you-started.html' title='Books needed to get you started'/><author><name>Rashmi Pandit</name><uri>http://www.blogger.com/profile/18034695514453106742</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15025668275518760866'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>