<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>chuyeow.wtf</title>
  <subtitle>Go, Ruby, Rails, Firefox, Anime, Mac</subtitle>
  <link rel="self" type="application/atom+xml" href="https://chuyeow.wtf/categories/ruby/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://chuyeow.wtf"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  <updated>2009-06-18T09:42:10+00:00</updated>
  <id>https://chuyeow.wtf/categories/ruby/feed.xml</id>
  <entry>
    <title>A curl-ier Curb - better cookie support in Curb</title>
    <published>2009-06-18T09:42:10+00:00</published>
    <updated>2009-06-18T09:42:10+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2009/06/18/better-cookie-support-in-curb/"/>
    <id>https://chuyeow.wtf/2009/06/18/better-cookie-support-in-curb/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2009/06/18/better-cookie-support-in-curb/">&lt;p&gt;As of &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;taf2&#x2F;curb&#x2F;tree&#x2F;master&quot;&gt;Curb&lt;&#x2F;a&gt; 0.3.7, Curb comes with slightly better cookie support that makes it more &quot;&lt;a href=&quot;http:&#x2F;&#x2F;curl.haxx.se&#x2F;&quot;&gt;curl&lt;&#x2F;a&gt;-like&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;It probably sounds like shameless self-promotion that I&#x27;m blogging about these changes since I&#x27;d contributed them. Well, yeah that&#x27;s true, but I&#x27;m also doing so because I doubt these changes will ever be made known since Curb doesn&#x27;t publicize any updates or changelogs. &lt;&#x2F;p&gt;
&lt;p&gt;Curb is my current number 1 HTTP client for Ruby so the more love it gets, the better.&lt;&#x2F;p&gt;
&lt;h3&gt;Passing cookies as a string in Curb requests&lt;&#x2F;h3&gt;
&lt;p&gt;Curl veterans will probably know how to do this with the curl binary:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;curl -b &quot;auth=abcdef; ASP.NET_SessionId=lotsatext;&quot; example.com&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This sends a request to example.com with 2 cookies named &quot;auth&quot; and &quot;ASP.NET_SessionId&quot; (I hate those big-ass ASP.NET cookies btw). There wasn&#x27;t a way to set this in Curb, so I looked up the &lt;a href=&quot;http:&#x2F;&#x2F;curl.haxx.se&#x2F;libcurl&#x2F;c&#x2F;&quot;&gt;libcurl C API docs&lt;&#x2F;a&gt; and replicated the same option in Curb (&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;taf2&#x2F;curb&#x2F;commit&#x2F;3c3e53c64a2417f78aa19f593a5f66e3ddffc969&quot;&gt;commit on Github&lt;&#x2F;a&gt;). An example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;curl = Curl::Easy.new(&#x27;http:&#x2F;&#x2F;example.com&#x2F;&#x27;)
curl.cookies = &#x27;auth=abcdef; ASP.NET_SessionId=big-wall-of-text;&#x27;
curl.perform&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, the cookies will more often be retrieved&#x2F;constructed rather than a literal like in the example above. In my case, I was proxying cookies while trying to wrap an API around a site that doesn&#x27;t have one.&lt;&#x2F;p&gt;
&lt;h3&gt;Passing cookies as a file via the &quot;cookiefile&quot; option&lt;&#x2F;h3&gt;
&lt;p&gt;The second change is the new &lt;code&gt;cookiefile&lt;&#x2F;code&gt; option. This replicates curl commands like these:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;curl -b cookies-to-send.txt www.example.com&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;with something like this in ruby:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;curl = Curl::Easy.new(&#x27;http:&#x2F;&#x2F;example.com&#x2F;&#x27;)
curl.cookiefile = &#x27;&#x2F;path&#x2F;to&#x2F;cookies-to-send.txt&#x27;
curl.perform&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The cookies file looks like this (you can get a sample with the &lt;code&gt;--cookie-jar&lt;&#x2F;code&gt; option to curl, e.g. &lt;code&gt;curl --cookie-jar cookies.txt www.wego.com&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;www.wego.com	FALSE	&#x2F;	FALSE	0	lang	
www.wego.com	FALSE	&#x2F;	FALSE	0	user_country_code	SG&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check out the &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;taf2&#x2F;curb&#x2F;commit&#x2F;a4910c25198441796f8e6d1958e144998833c7ec&quot;&gt;commit on Github&lt;&#x2F;a&gt; if you&#x27;re interested.&lt;&#x2F;p&gt;
&lt;h3&gt;Why would I use these?&lt;&#x2F;h3&gt;
&lt;p&gt;Now you might be wondering how these 2 changes are useful - well, they &lt;em&gt;are&lt;&#x2F;em&gt; totally irrelevant to you if you&#x27;re not expecting any cookie support in Curb. However, if you&#x27;re accessing or scraping a site that uses &lt;strong&gt;cookie-based authentication&lt;&#x2F;strong&gt;, these changes allow you to keep your Curb client authenticated across sessions, even when doing HTTP POSTs (Curb doesn&#x27;t send cookies properly in POST requests even if &lt;code&gt;curl.enable_cookies&lt;&#x2F;code&gt; is set).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve found these changes to Curb particularly useful since I vastly prefer Curb to most HTTP clients for its speed and lightweight implementation, and heavier scraper-type HTTP clients like &lt;a href=&quot;http:&#x2F;&#x2F;mechanize.rubyforge.org&#x2F;mechanize&#x2F;&quot;&gt;Mechanize&lt;&#x2F;a&gt; are a last resort.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Don&#x27;t kill your app when using ActiveRecord in Rails Metal, release your database connections</title>
    <published>2009-06-15T14:49:51+00:00</published>
    <updated>2009-06-15T14:49:51+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2009/06/15/activerecord-rails-metal-too-many-connections/"/>
    <id>https://chuyeow.wtf/2009/06/15/activerecord-rails-metal-too-many-connections/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2009/06/15/activerecord-rails-metal-too-many-connections/">&lt;p&gt;Rails Metal has been available on Rails since version 2.3 - it&#x27;s old news. But if you haven&#x27;t used it or heard about it, you can find out more about Rails Metal on the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2008&#x2F;12&#x2F;17&#x2F;introducing-rails-metal&quot;&gt;RoR weblog&lt;&#x2F;a&gt; and on &lt;a href=&quot;http:&#x2F;&#x2F;soylentfoo.jnewland.com&#x2F;articles&#x2F;2008&#x2F;12&#x2F;16&#x2F;rails-metal-a-micro-framework-with-the-power-of-rails-m&quot;&gt;Jesse Newland&#x27;s blog&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So anyway, I am one of those laggards and only wrote a Rails Metal piece not too long ago for a Rails app on &lt;a href=&quot;http:&#x2F;&#x2F;www.wego.com&#x2F;&quot;&gt;Wego.com&lt;&#x2F;a&gt; in an effort to optimize some high volume requests. It looked something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Adamantine
  def self.call(env)
    if env[&#x27;PATH_INFO&#x27;] =~ ROUTE_REGEX
      location = Location.find(1) # Use ActiveRecord.
&lt;pre&gt;&lt;code&gt;  [200, { &amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text&#x2F;html&amp;#39; }, [location.to_json]]
else
  # Leave it to Rails to deal with the request.
  [404, { &amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text&#x2F;html&amp;#39; }, [&amp;#39;Not Found&amp;#39;]]
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice the use of an ActiveRecord model. It ran for quite awhile, almost 30 minutes, in &lt;em&gt;production&lt;&#x2F;em&gt; until I started getting notification emails about &quot;&lt;strong&gt;Too many open database connections&lt;&#x2F;strong&gt;&quot; to the MySQL server! The change was promptly rolled back and there was no cheezburger for me.&lt;&#x2F;p&gt;
&lt;p&gt;As it turns out, Rails doesn&#x27;t take care of certain things in Rails Metal pieces, including the releasing of connections back to the database connection pool. A bit of googling turned up this &lt;a href=&quot;https:&#x2F;&#x2F;rails.lighthouseapp.com&#x2F;projects&#x2F;8994&#x2F;tickets&#x2F;1882-rails-metal-with-activerecord-too-slow&quot;&gt;bug in Rails&#x27; bug tracker&lt;&#x2F;a&gt; (see Josh Peek&#x27;s comment about &lt;code&gt;ActiveRecord::Base.clear_active_connections!&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;I rewrote the Rails Metal piece to always ensure it clears any active database connections with &lt;code&gt;ActiveRecord::Base.clear_active_connections!&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Adamantine
  def self.call(env)
    if env[&#x27;PATH_INFO&#x27;] =~ ROUTE_REGEX
      location = Location.find(1)
&lt;pre&gt;&lt;code&gt;  [200, { &amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text&#x2F;html&amp;#39; }, [location.to_json]]
else
  # Leave it to Rails to deal with the request.
  [404, { &amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text&#x2F;html&amp;#39; }, [&amp;#39;Not Found&amp;#39;]]
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ensure
# Release the connections back to the pool.
ActiveRecord::Base.clear_active_connections!
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Moral of the story: Don&#x27;t forget to release your database connections if you&#x27;re using ActiveRecord in your Rails Metal. Or even better, don&#x27;t use ActiveRecord in Rails Metal - you&#x27;re aiming for raw speed anyway right?&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) has a new home at the Official Ruby on Rails weblog</title>
    <published>2008-06-22T17:55:39+00:00</published>
    <updated>2008-06-22T17:55:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/"/>
    <id>https://chuyeow.wtf/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/">&lt;p&gt;You may have &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2008&#x2F;6&#x2F;10&#x2F;two-new-weekly-columns&quot;&gt;heard of it&lt;&#x2F;a&gt;, but just in case, &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;category&#x2F;edge-rails&#x2F;&quot;&gt;Living on the Edge&lt;&#x2F;a&gt; is now going to be published on the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;&quot;&gt;official Ruby on Rails weblog&lt;&#x2F;a&gt;. Big thanks to &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;&quot;&gt;Gregg Pollack&lt;&#x2F;a&gt; for getting me the new &quot;gig&quot;, and more importantly, for reviving and freshening up the content on the official Rails blog.&lt;&#x2F;p&gt;
&lt;p&gt;Catch the new first edition - this one&#x27;s about the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2008&#x2F;6&#x2F;20&#x2F;living-on-the-edge-or-what-s-new-in-edge-rails-1-api-changes-and-performancetests&quot;&gt;API changes since Rails 2.1&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #22 - pre-Railsconf 2008 edition</title>
    <published>2008-05-25T19:06:36+00:00</published>
    <updated>2008-05-25T19:06:36+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/"/>
    <id>https://chuyeow.wtf/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/">&lt;p&gt;No mind-blowing changes in Rails this week prior to RailsConf - as Gregg mentioned last week in the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;5&#x2F;21&#x2F;rails-envy-podcast-episode-032&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt;, it&#x27;s pre-2.1 days (Rails 2.1 will &lt;em&gt;probably&lt;&#x2F;em&gt; be released at RailsConf) so it&#x27;s pretty easy to see why. Oh and all Rails tests now pass in Ruby 1.9 after a long-standing &lt;code&gt;#module_eval&lt;&#x2F;code&gt; bug got fixed in Ruby 1.9&#x27;s trunk (see &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;ruby-core-google&#x2F;browse_thread&#x2F;thread&#x2F;6d08e11363bf49b4&quot;&gt;thread&lt;&#x2F;a&gt; for more details).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be at (my first) Railsconf 2008 in Portland, Oregon this Thursday onwards - if anyone sees me and recognizes me from my &lt;a href=&quot;http:&#x2F;&#x2F;www.facebook.com&#x2F;people&#x2F;Chu_Yeow&#x2F;500115784&quot;&gt;Facebook picture&lt;&#x2F;a&gt; please come and say hi (no head butting though).&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 19th May 2008 to 25th May 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;first and last methods now work with associations and named_scope&lt;&#x2F;h3&gt;
&lt;p&gt;Remember how the &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;04&#x2F;05&#x2F;living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late&#x2F;&quot;&gt;merging of the has_finder gem into Rails&lt;&#x2F;a&gt; allowed you to do things like &lt;code&gt;Post.first&lt;&#x2F;code&gt; and &lt;code&gt;Post.last&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Now you can go one step further and use the same methods on your ActiveRecord associations. For example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;post = Post.find(1)
first_comment = post.comments.first&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have a &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2008&#x2F;3&#x2F;24&#x2F;what-s-new-in-edge-rails-has-finder-functionality&quot;&gt;named_scope&lt;&#x2F;a&gt; named &lt;code&gt;recent&lt;&#x2F;code&gt; defined, you can even do this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;post.comments.recent.last&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This neat little enhancement is courtesy of &lt;a href=&quot;http:&#x2F;&#x2F;railscasts.com&#x2F;&quot;&gt;Ryan Bates&lt;&#x2F;a&gt; (yes, that &lt;em&gt;Ryan Bates&lt;&#x2F;em&gt; of &lt;a href=&quot;http:&#x2F;&#x2F;railscasts.com&#x2F;&quot;&gt;Railscasts&lt;&#x2F;a&gt; fame).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;73c59638549686fccc749ffd3ac53cb533c5fd61&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;73c59638549686fccc749ffd3ac53cb533c5fd61&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Cache stores now have an exist? method and controllers get fragment_exist?&lt;&#x2F;h3&gt;
&lt;p&gt;The cache stores in Rails (Memcache, file stores, etc.) now have an &lt;code&gt;exist?&lt;&#x2F;code&gt; method that checks whether a cached value exists given a cache key. This allows Rails controllers to expose a &lt;code&gt;fragment_exist?&lt;br &#x2F;&gt;
&lt;&#x2F;code&gt; method that allows you to check for existence of a cache fragment:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;fragment_exist?(&#x27;example.com&#x2F;foo&#x2F;bar&#x27;)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This little enhancement is courtesy of &lt;a href=&quot;http:&#x2F;&#x2F;josevalim.blogspot.com&#x2F;&quot;&gt;José Valim&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;99860b72aebe0348f41e82d4710343498d89a84b#diff-2&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;99860b72aebe0348f41e82d4710343498d89a84b#diff-2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Create association records with block argument&lt;&#x2F;h3&gt;
&lt;p&gt;You can now create records for associations like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;post.coments.create!(:title =&gt; &#x27;Techcrunch&#x27;) do |c|
  c.body = &quot;Rails can&#x27;t scale&quot;
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is in keeping with the &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;05&#x2F;04&#x2F;living-on-the-edge-of-rails-19-change_table-for-migrations-and-more&#x2F;&quot;&gt;ActiveRecord::Base.create change previously mentioned&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Credit for this patch goes (once again) to &lt;a href=&quot;http:&#x2F;&#x2F;railscasts.com&#x2F;&quot;&gt;Ryan Bates&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;6cba97d2a449faf21aec9fe9d4434067e414226f&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;6cba97d2a449faf21aec9fe9d4434067e414226f&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) in Spanish</title>
    <published>2008-05-18T20:16:18+00:00</published>
    <updated>2008-05-18T20:16:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-in-spanish/"/>
    <id>https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-in-spanish/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-in-spanish/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;sobrerailes.com&#x2F;&quot;&gt;Juan Lupión&lt;&#x2F;a&gt; wrote in to inform me that he&#x27;s also translating my Living on the Edge (of Rails) series of blog posts to Español. Thanks Juan!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #21</title>
    <published>2008-05-18T19:54:42+00:00</published>
    <updated>2008-05-18T19:54:42+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-21/"/>
    <id>https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-21/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/18/living-on-the-edge-of-rails-21/">&lt;p&gt;It&#x27;s another slow week (just 2 changes of note &lt;acronym title=&quot;in my humble opinion&quot;&gt;imho&lt;&#x2F;acronym&gt;) after the &lt;a href=&quot;http:&#x2F;&#x2F;www.rubyinside.com&#x2F;rails-21-released-891.html&quot;&gt;release of the 1st Release Candidate (RC1) of Rails 2.1&lt;&#x2F;a&gt;. Follow that link for installation instructions - though if you&#x27;re reading this blog post you probably don&#x27;t care! (because you&#x27;re, you know, &quot;living on the edge&quot;). Cheesiness aside, be sure to report any bugs you may encounter when upgrading to 2.1 RC1 or edge at the &lt;a href=&quot;http:&#x2F;&#x2F;rails.lighthouseapp.com&#x2F;projects&#x2F;8994-ruby-on-rails&#x2F;overview&quot;&gt;Rails bug tracker&lt;&#x2F;a&gt; - it is an RC so any bug reports would be very welcome and useful!&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 12th May 2008 to 18th May 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;caches_action can has conditionals&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;caches_action&lt;&#x2F;code&gt; now takes an &lt;code&gt;:if&lt;&#x2F;code&gt; option (just like &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;04&#x2F;20&#x2F;living-on-the-edge-of-rails-17&#x2F;&quot;&gt;caches_page does&lt;&#x2F;a&gt;). For example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;caches_action :index, :if =&amp;gt; Proc.new { |c| !c.request.format.json? }&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This little enhancement is courtesy of José Valim.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;7708650f73ddb4db300ea2059c60c1d907a4384e&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;7708650f73ddb4db300ea2059c60c1d907a4384e&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Bugfix: :select option is now scanned in ActiveRecord finders to ensure needed tables are included in generated SQL&lt;&#x2F;h3&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Post.find(:all, :include =&amp;gt; :author, :select =&amp;gt; &#x27;posts.*, authors.id as &quot;author_id&quot;&#x27;, :limit =&amp;gt; 2)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Would generate an SQL statement like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;sql&quot;&gt;SELECT posts.*, authors.id as &quot;author_id&quot; FROM &quot;posts&quot; LIMIT 2&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice how the &lt;code&gt;authors&lt;&#x2F;code&gt; table is not joined. This oversight is now fixed.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks go to John Devine for this bugfix.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;b28b54cab090bed8f099ef375b419a8f92390dd4&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;b28b54cab090bed8f099ef375b419a8f92390dd4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series. Also, if anyone has any recommendations of (non-ruby-related) things to do in Portland, do let me know!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Deploying with Capistrano via a gateway - some notes</title>
    <published>2008-05-15T17:03:48+00:00</published>
    <updated>2008-05-15T17:03:48+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/15/deploying-with-capistrano-via-a-gateway/"/>
    <id>https://chuyeow.wtf/2008/05/15/deploying-with-capistrano-via-a-gateway/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/15/deploying-with-capistrano-via-a-gateway/">&lt;p&gt;Some notes on setting up a &lt;a href=&quot;http:&#x2F;&#x2F;weblog.jamisbuck.org&#x2F;2006&#x2F;9&#x2F;26&#x2F;inside-capistrano-the-gateway-implementation&quot;&gt;gateway server for deploying via Capistrano&lt;&#x2F;a&gt; that I couldn&#x27;t find at &lt;a href=&quot;http:&#x2F;&#x2F;capify.org&#x2F;getting-started&#x2F;basics&quot;&gt;the source&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can specify the user you want to use to login to your gateway server like so: &lt;code&gt;set :gateway, &#x27;deploy@deploy.example.com&#x27;&lt;&#x2F;code&gt;. This logs in to your gateway server as the &quot;deploy&quot; user.&lt;&#x2F;li&gt;
&lt;li&gt;You can specify an alternate SSH port for both your gateway &lt;em&gt;and&lt;&#x2F;em&gt; your deployment servers. E.g. setting &lt;code&gt;ssh_options[:port] = 11111&lt;&#x2F;code&gt; will make Capistrano SSH to your gateway server with on port 11111. For your actual application (and web and database) servers, you can specify the SSH port like so:
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;set :gateway, &#x27;deploy@deploy.example.com&#x27;
role :app, &#x27;192.168.1.113:22222&#x27;
role :web, &#x27;192.168.1.113:22222&#x27;
role :db,  &#x27;192.168.1.113:22222&#x27;, :primary =&gt; true&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If you&#x27;re using public key authentication, you should put the public keys of your users (those who be deploying your app) on the gateway server &lt;em&gt;and&lt;&#x2F;em&gt; on the actual servers. I thought Capistrano would use the key of the &quot;deploy&quot; user but nope.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #19 - change_table for migrations and more</title>
    <published>2008-05-04T20:18:54+00:00</published>
    <updated>2008-05-04T20:18:54+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/"/>
    <id>https://chuyeow.wtf/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/">&lt;p&gt;This week’s report covers changes from 29 April 2008 to 4th May 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;change_table for ActiveRecord migrations&lt;&#x2F;h3&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;zilkey.com&#x2F;&quot;&gt;Jeff Dean&lt;&#x2F;a&gt;, who also &lt;a href=&quot;http:&#x2F;&#x2F;zilkey.com&#x2F;2008&#x2F;4&#x2F;29&#x2F;new-rails-core-feature-proposal-super-sexy-migrations&quot;&gt;blogged about the new change_table feature in ActiveRecord migrations&lt;&#x2F;a&gt;, you can now change a table with a block like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;change_table :videos do |t|
  t.add_timestamps
  t.add_belongs_to :goat
  t.add_string :name, :email, :limit =&amp;gt; 20
  t.remove_column :name, :email # takes multiple arguments
  t.rename :new_name
  t.string :new_string_column # executes against the renamed table name
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some key things to note:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add_XXX&lt;&#x2F;code&gt; would add a new column for you, e.g. &lt;code&gt;add_string&lt;&#x2F;code&gt; would add a new string field.&lt;&#x2F;li&gt;
&lt;li&gt;Of course, add_timestamps would add the magic &lt;code&gt;created_at&lt;&#x2F;code&gt; and &lt;code&gt;updated_at&lt;&#x2F;code&gt; datetime fields.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;remove_column&lt;&#x2F;code&gt; now takes multiple arguments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;rename&lt;&#x2F;code&gt; would rename the table.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Very nice, DRY enhancement, props to &lt;a href=&quot;http:&#x2F;&#x2F;zilkey.com&#x2F;&quot;&gt;Jeff Dean&lt;&#x2F;a&gt; once again.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;96980bd561d79824b6cb6efbcbecdcbf8785d452&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;96980bd561d79824b6cb6efbcbecdcbf8785d452&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord::Base.create takes a block like ActiveRecord::Base.new&lt;&#x2F;h3&gt;
&lt;p&gt;Yup now you can also &lt;code&gt;create&lt;&#x2F;code&gt; ActiveRecord objects with a block argument just like you could for &lt;code&gt;ActiveRecord::Base.new&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;@person = Person.create(params[:person]) do |p|
  p.name = &#x27;Konata Izumi&#x27;
  p.age = 17
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;11022-adam-meehan&quot;&gt;Adam Meehan&lt;&#x2F;a&gt; for this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;dd120ede53eaf71dee76894998a81626b7a689fc&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;dd120ede53eaf71dee76894998a81626b7a689fc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Bugfix: change_column should be able to use :null =&gt; true on a field that&lt;br &#x2F;&gt;
formerly had false&lt;&#x2F;h3&gt;
&lt;p&gt;You can now use &lt;code&gt;change_column&lt;&#x2F;code&gt; in your migrations to alter a column as nullable if it was previously &lt;code&gt;NOT NULL&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This bugfix is courtesy of Nate Wiger.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;10ef65a3b054270ed3d458ec8eb7c2b9a3e638f7&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;10ef65a3b054270ed3d458ec8eb7c2b9a3e638f7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) in French</title>
    <published>2008-05-01T00:07:34+00:00</published>
    <updated>2008-05-01T00:07:34+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/01/living-on-the-edge-of-rails-in-french/"/>
    <id>https://chuyeow.wtf/2008/05/01/living-on-the-edge-of-rails-in-french/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/01/living-on-the-edge-of-rails-in-french/">&lt;p&gt;It looks like &lt;a href=&quot;http:&#x2F;&#x2F;blog.shingara.fr&#x2F;&quot;&gt;Cyril Mougel&lt;&#x2F;a&gt; has translated my 2 latest posts to French: &lt;a href=&quot;http:&#x2F;&#x2F;blog.shingara.fr&#x2F;articles&#x2F;2008&#x2F;04&#x2F;24&#x2F;vivre-avec-rails-edge-17&quot;&gt;LotE #17&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;blog.shingara.fr&#x2F;articles&#x2F;2008&#x2F;04&#x2F;29&#x2F;vivre-avec-rails-edge-18&quot;&gt;#18&lt;&#x2F;a&gt;. Thanks Cyril!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #18</title>
    <published>2008-04-27T19:18:36+00:00</published>
    <updated>2008-04-27T19:18:36+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/27/living-on-the-edge-of-rails-18/"/>
    <id>https://chuyeow.wtf/2008/04/27/living-on-the-edge-of-rails-18/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/27/living-on-the-edge-of-rails-18/">&lt;p&gt;This week’s report covers changes from 21 Apr 2008 to 27 Apr 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;p&gt;Not much interesting to report this week - there were mostly a bunch of bugfixes and Ruby 1.8.7-compatibility &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commits&#x2F;master&quot;&gt;commits&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Introduce ActiveResource::Base.timeout and rescuing from Timeout::Error in ActiveResource::Connection&lt;&#x2F;h3&gt;
&lt;p&gt;These are &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;105910429d5873dce677ef32eef5f705e0625d86&quot;&gt;2&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;cf32baf915442ffe153ec0e4d8148f147776c30a&quot;&gt;changes&lt;&#x2F;a&gt; that I&#x27;d &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;04&#x2F;22&#x2F;new-in-rails-activeresource-timeouts-and-why-it-matters&#x2F;&quot;&gt;talked about&lt;&#x2F;a&gt; earlier this week so I won&#x27;t repeat myself - take a read through &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;04&#x2F;22&#x2F;new-in-rails-activeresource-timeouts-and-why-it-matters&#x2F;&quot;&gt;ActiveResource timeouts and why it matters&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Smart integer datatype for the MySQL adapter in migrations&lt;&#x2F;h3&gt;
&lt;p&gt;The MySQL adapter in Rails now maps the &lt;code&gt;integer&lt;&#x2F;code&gt; column type in your migrations to either smallint, int, or bigint depending on the :limit option.&lt;&#x2F;p&gt;
&lt;p&gt;This means that a migration like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def self.up
  create_table :searches do |t|
    t.integer :foo, :limit =&gt; 2
  end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will create your &lt;code&gt;foo&lt;&#x2F;code&gt; column as a &lt;code&gt;smallint(2)&lt;&#x2F;code&gt; MySQL datatype (instead of &lt;code&gt;int(2)&lt;&#x2F;code&gt; before). (More information &lt;a href=&quot;http:&#x2F;&#x2F;dev.mysql.com&#x2F;doc&#x2F;refman&#x2F;5.0&#x2F;en&#x2F;numeric-types.html&quot;&gt;MySQL numeric datatypes&lt;&#x2F;a&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to DHH for this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;a37546517dad9f6d9a7de6e1dba4d960909d71e8&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;a37546517dad9f6d9a7de6e1dba4d960909d71e8&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Rails: ActiveResource timeouts and why it matters</title>
    <published>2008-04-22T22:25:57+00:00</published>
    <updated>2008-04-22T22:25:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/"/>
    <id>https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/">&lt;p&gt;If you&#x27;ve ever used ActiveResource or for that matter, coded anything that involves interacting with a remote API, you&#x27;ve probably had the misfortune of having that API go down or become unresponsive. The experienced old geezers would already have forseen the problem and set a timeout on those API calls. For the rest of us, it&#x27;s a good time to get acquainted with the idea of &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fail-fast&quot;&gt;fail-fast&lt;&#x2F;a&gt; and how &lt;em&gt;no response is better than a slow response&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So what happens when the API you&#x27;re accessing via ActiveResource or &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; (or whatever, really, so long as there&#x27;s a network socket involved!) becomes unresponsive?&lt;&#x2F;p&gt;
&lt;h3&gt;Unfettered outbound remote connections can kill your server&lt;&#x2F;h3&gt;
&lt;p&gt;ActiveResource (or &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; or whatever you&#x27;re using) would block while waiting for the API to return. What did we learn about blocking IO in Operating Systems 101? That your process or thread gets stuck waiting for a response that&#x27;s what. So now your Mongrel&#x2F;Thin&#x2F;Ebb&#x2F;X web server process basically stuck waiting for a response from an API that might return a response in 30 seconds, or maybe it&#x27;ll never return at all. It won&#x27;t be long before all your web server processes get blocked and its time to &quot;kill dash nine&quot; (&lt;code&gt;kill -9&lt;&#x2F;code&gt;) some processes and bring out the 500 error page. Yes, your server has been incapacitated and your website is now basically offline.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;im-in-ur-serverz.gif&quot; alt=&quot;im in ur serverz making thingz better&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Timeouts and you&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;re using Net::HTTP you can easily safeguard yourself against errors like this by setting a timeout on the socket connection. Like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def fetch_something_from_some_api(uri)
  http = Net::HTTP.new(uri.host, uri.port)
  http.read_timeout = timeout
&lt;p&gt;response = http.start { http.request(Net::HTTP::Get.new(&quot;#{uri.path}?#{uri.query}&quot;)) }
response.is_a?(Net::HTTPSuccess) ? do_something_with(response.body) : nil
rescue Timeout::Error
logger.warn(&quot;Timeout accessing #{uri}: #{$!}&quot;)
nil
rescue
logger.warn(&quot;Error accessing #{uri}: #{$!}&quot;)
nil
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take note that you really do need to explicitly rescue from the &lt;code&gt;Timeout::Error&lt;&#x2F;code&gt; (or &lt;code&gt;Interrupt&lt;&#x2F;code&gt;) since it&#x27;s a child of the &lt;code&gt;Interrupt&lt;&#x2F;code&gt; class and not a &lt;code&gt;StandardError&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Any good client library should also allow you to specify a timeout on the socket connection so read the API documentation.&lt;&#x2F;p&gt;
&lt;h3&gt;So what&#x27;s this about ActiveResource?&lt;&#x2F;h3&gt;
&lt;p&gt;So back to ActiveResource: Michael Koziarski was kind enough to commit my 2 patches (&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;105910429d5873dce677ef32eef5f705e0625d86&quot;&gt;this&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;cf32baf915442ffe153ec0e4d8148f147776c30a&quot;&gt;this&lt;&#x2F;a&gt;) to ActiveResource so now on &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;tree&#x2F;master&quot;&gt;edge Rails&lt;&#x2F;a&gt;, you can do this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Person &amp;lt; ActiveResource::Base
  self.site = &#x27;http:&#x2F;&#x2F;api.people.com:3000&#x2F;&#x27;
  self.timeout = 5
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This sets the timeout to 5 seconds on the underlying &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; instance that ActiveResource uses. The default timeout (to be exact, the &lt;code&gt;read_timeout&lt;&#x2F;code&gt;) for &lt;code&gt;Net::HTTP&lt;&#x2F;code&gt; is &lt;strong&gt;60 seconds&lt;&#x2F;strong&gt; on most Ruby implementations (that includes MRI). That&#x27;s far too long if your ActiveResource call is in a public-facing controller!&lt;&#x2F;p&gt;
&lt;p&gt;If you are using ActiveResource anywhere and haven&#x27;t safeguarded your application with a timeout, I think it&#x27;s a good idea to fix it by using edge Rails or at least applying the &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;105910429d5873dce677ef32eef5f705e0625d86&quot;&gt;patch&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;cf32baf915442ffe153ec0e4d8148f147776c30a&quot;&gt;2nd ActiveResource patch&lt;&#x2F;a&gt; introduces the &lt;code&gt;ActiveResource::TimeoutError&lt;&#x2F;code&gt; exception that you should rescue from whenever you make an ActiveResource call. When this happens, it&#x27;s up to your application to decide what to do (like show a placating we&#x27;re sorry message). At least your application is still able to do something!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #17</title>
    <published>2008-04-20T19:21:22+00:00</published>
    <updated>2008-04-20T19:21:22+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/20/living-on-the-edge-of-rails-17/"/>
    <id>https://chuyeow.wtf/2008/04/20/living-on-the-edge-of-rails-17/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/20/living-on-the-edge-of-rails-17/">&lt;p&gt;Not much going on this week on edge Rails. It does seem however that we do have a new Rails core member, &lt;a href=&quot;http:&#x2F;&#x2F;joshpeek.com&#x2F;&quot;&gt;Joshua Peek&lt;&#x2F;a&gt;. Also, the new &lt;a href=&quot;http:&#x2F;&#x2F;rails.lighthouseapp.com&#x2F;&quot;&gt;Rails&#x27; bug tracker&lt;&#x2F;a&gt; hosted on Lighthouse is ready for use, so be sure to submit your patches and bug reports there.&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 14 Apr 2008 to 20 Apr 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Conditional caches_page&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;caches_page&lt;&#x2F;code&gt; now takes an &lt;code&gt;:if&lt;&#x2F;code&gt; option for specifying when a page can actually be cached via a Proc. You can now do this, for example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;caches_page :index, :if =&amp;gt; Proc.new { |c| !c.request.format.json? }&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That will only cache your index page if the requested format is not JSON.&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;deaddeadgood.com&#x2F;&quot;&gt;Paul Horsfall&lt;&#x2F;a&gt; for this enhancement.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;14a40804a29a57ad05ca6bffbe1e5334089593a9&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;14a40804a29a57ad05ca6bffbe1e5334089593a9&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;New ActionView::TestCase for testing view helpers&lt;&#x2F;h3&gt;
&lt;p&gt;Remember how you can now use &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;27&#x2F;dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7&#x2F;&quot;&gt;specialized TestCase classes for testing controllers and ActionMailer classes&lt;&#x2F;a&gt;? Now you can do the same with your Rails view helpers with the new ActionView::TestCase class.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a quick example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module PeopleHelper
  def title(text)
    content_tag(:h1, text)
  end
&lt;p&gt;def homepage_path
people_path
end
end&lt;&#x2F;p&gt;
&lt;p&gt;class PeopleHelperTest &amp;lt; ActionView::TestCase
def setup
ActionController::Routing::Routes.draw do |map|
map.people &#x27;people&#x27;, :controller =&amp;gt; &#x27;people&#x27;, :action =&amp;gt; &#x27;index&#x27;
map.connect &#x27;:controller&#x2F;:action&#x2F;:id&#x27;
end
end&lt;&#x2F;p&gt;
&lt;p&gt;def test_title
assert_equal &quot;&amp;lt;h1&amp;gt;Ruby on Rails&amp;lt;&#x2F;h1&amp;gt;&quot;, title(&quot;Ruby on Rails&quot;)
end&lt;&#x2F;p&gt;
&lt;p&gt;def test_homepage_path
assert_equal &quot;&#x2F;people&quot;, homepage_path
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to Josh Peek for this sweet little enhancement.&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveSupport::Cache&#x27;s mem_cache_store accepts options&lt;&#x2F;h3&gt;
&lt;p&gt;Even though Memcache-client was added to ActiveSupport recently, it didn&#x27;t allow you to specify any configuration options beyond just the IP of the memcached server. Now you can pass along more configuration options like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;config.action_controller.fragment_cache_store = :mem_cache_store, &#x27;localhost&#x27;, { :compression =&amp;gt; true, :debug =&amp;gt; true, :namespace =&amp;gt; &#x27;foo&#x27; }&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This patch is courtesy of &lt;a href=&quot;http:&#x2F;&#x2F;blog.innerewut.de&#x2F;&quot;&gt;Jonathan Weiss&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;9e1d506a8cfedef2fdd605e4cbf4bf53651ad214&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;9e1d506a8cfedef2fdd605e4cbf4bf53651ad214&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #16 - Github edition</title>
    <published>2008-04-13T16:09:43+00:00</published>
    <updated>2008-04-13T16:09:43+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/13/living-on-the-edge-of-rails-16-github-edition/"/>
    <id>https://chuyeow.wtf/2008/04/13/living-on-the-edge-of-rails-16-github-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/13/living-on-the-edge-of-rails-16-github-edition/">&lt;p&gt;A slight change this week since &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2008&#x2F;4&#x2F;11&#x2F;rails-premieres-on-github&quot;&gt;Rails has moved to Git&lt;&#x2F;a&gt; - all changesets are now referenced to &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;tree&#x2F;master&quot;&gt;Github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 7 Apr 2008 to 13 Apr 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;A helpers proxy method for accessing helper methods from outside of views&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;helpers&lt;&#x2F;code&gt; method has been introduced to ActionController - you can now access your helpers like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ApplicationController.helpers.simple_format(text)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to 19 year old &lt;a href=&quot;http:&#x2F;&#x2F;joshpeek.com&#x2F;&quot;&gt;Josh Peek&lt;&#x2F;a&gt;, one of the more prolific Rails contributors (and most likely to join Pratik in Rails Core imo).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;917423d664038d6791738a73ad1446437dbb71df&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;917423d664038d6791738a73ad1446437dbb71df&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;json_escape for escaping HTML entities in JSON strings&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;json_escape&lt;&#x2F;code&gt; (aliased as &lt;code&gt;j&lt;&#x2F;code&gt;, similar to how &lt;code&gt;html_escape&lt;&#x2F;code&gt; is aliased as &lt;code&gt;h&lt;&#x2F;code&gt;) has been introduced by Rick Olson for escaping HTML entities in JSON strings. This is useful if you find yourself emitting JSON strings in HTML pages (e.g. for documenting a JSON API):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;json_escape(&quot;is a &amp;gt; 0 &amp;amp; a &amp;lt; 10?&quot;)
# =&gt; is a \u003E 0 \u0026 a \u003C 10?&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, since &lt;code&gt;json_escape&lt;&#x2F;code&gt; is aliased as &lt;code&gt;j&lt;&#x2F;code&gt;, you can do this in your ERB templates:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;%=j @person.to_json %&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;0ff7a2d89fc95dcb0a32ed92aab7156b0778a7ea&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;0ff7a2d89fc95dcb0a32ed92aab7156b0778a7ea&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Automatically parse posted JSON content for Mime::JSON requests&lt;&#x2F;h3&gt;
&lt;p&gt;Rails will now accept POSTed JSON content! For example, you can now send a POST to &quot;&#x2F;posts&quot; of your Post resource like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;POST &#x2F;posts
{&quot;post&quot;: {&quot;title&quot;: &quot;Breaking News&quot;}}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And your &lt;code&gt;create&lt;&#x2F;code&gt; action will automatically parse the POSTed JSON into the request &lt;code&gt;params&lt;&#x2F;code&gt; so that this code below just works:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def create
  @post = Post.create params[:post]
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to Rick Olson.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;4d594cffcfc93b37fad4e423ec8593299e50133c&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;4d594cffcfc93b37fad4e423ec8593299e50133c&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;schema_migrations table replaces the schema_info table, allowing for interleaved migrations&lt;&#x2F;h3&gt;
&lt;p&gt;A new schema_migrations table for storing which migrations have been run has been introduced, and this replaces the existing schema_info table (which simply keeps track of the last applied schema version). This change makes it possible to add migrations (for example, after you&#x27;ve merged from someone&#x27;s branch) - when you migrate your database via rake db:migrate, those never-applied &quot;interleaved&quot; migrations will be run. Similarly, when migrating down schema versions, never-applied &quot;interleaved&quot; will be skipped.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;11493&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;11493&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
&lt;p&gt;This useful patch is the brainchild of &lt;a href=&quot;http:&#x2F;&#x2F;bunster.org&#x2F;&quot;&gt;Jordi Bunster&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;12130-jordi-bunster&quot;&gt;WWR profile&lt;&#x2F;a&gt;). I&#x27;m sure many Rails developers who branch extensively will thank Jordi for this excellent patch!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;gems:unpack:dependencies Rake task&lt;&#x2F;h3&gt;
&lt;p&gt;Remember how you can now run the &lt;code&gt;gems:unpack&lt;&#x2F;code&gt; Rake task to unpack a gem into your &lt;code&gt;vendor&#x2F;gems&#x2F;&lt;&#x2F;code&gt; directory (this was &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;04&#x2F;05&#x2F;living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late&#x2F;&quot;&gt;mentioned in an earlier Living on the Edge&lt;&#x2F;a&gt;)?&lt;&#x2F;p&gt;
&lt;p&gt;David Dollar (&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;ddollar&quot;&gt;Github profile&lt;&#x2F;a&gt;) has firmed up that patch quite a bit by adding the &lt;code&gt;gems:unpack:dependencies&lt;&#x2F;code&gt; Rake task that unpacks the dependencies of the gems as well. So running:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;gems:unpack:dependencies GEM=activecouch&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;would unpack the full Rubygem dependency tree of gems that the &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;activecouch&#x2F;&quot;&gt;activecouch&lt;&#x2F;a&gt; gem depends upon.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;4364c361b599f99bc2345ce4eb2d145b07ed8a0f&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;commit&#x2F;4364c361b599f99bc2345ce4eb2d145b07ed8a0f&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series! Now go out there and start &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;tree&#x2F;master&quot;&gt;forking Rails&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #15 - the early edition</title>
    <published>2008-04-06T15:57:01+00:00</published>
    <updated>2008-04-06T15:57:01+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/"/>
    <id>https://chuyeow.wtf/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/">&lt;p&gt;I&#x27;m gonna post up the Living on the Edge a little earlier this week because I&#x27;ve found I just can&#x27;t keep up (when things get busy) with 2 separate sets of notes for the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; and another for my own blog posts.&lt;&#x2F;p&gt;
&lt;p&gt;From this week onwards, I&#x27;ll be following &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&quot;&gt;Pratik&lt;&#x2F;a&gt;&#x27;s suggestion to post about changes as they happen instead of after an entire week so expect a slight change in the format of Living on the edge for next week!&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 31 Mar 2008 to 6 Apr 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Rails.env, Rails.logger, Rails.cache, Rails.root&lt;&#x2F;h3&gt;
&lt;p&gt;This has been a long time coming: You can now use &lt;code&gt;Rails.env&lt;&#x2F;code&gt; instead of &lt;code&gt;RAILS_ENV&lt;&#x2F;code&gt;, &lt;code&gt;Rails.root&lt;&#x2F;code&gt; instead of &lt;code&gt;RAILS_ROOT&lt;&#x2F;code&gt;, &lt;code&gt;Rails.logger&lt;&#x2F;code&gt; instead of &lt;code&gt;RAILS_DEFAULT_LOGGER&lt;&#x2F;code&gt;, and &lt;code&gt;Rails.cache&lt;&#x2F;code&gt; instead of &lt;code&gt;RAILS_CACHE&lt;&#x2F;code&gt;. Not having to use constants is nice because it always felt a bit dirty to have so many hard-coded constants in the Rails namespace.&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;Pratik Naik&lt;&#x2F;a&gt;, the newest Rails core team member for this cleanup.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9180&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9180&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Render :partial now works with a collection of heterogeneous elements&lt;&#x2F;h3&gt;
&lt;p&gt;You can now use &lt;code&gt;render :partial&lt;&#x2F;code&gt; to render a collection of different elements and Rails will figure out which partial template to use. For example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;render :partial =&gt; [ monkey, donkey, dramatic_chipmunk ]&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will render the monkey with the &#x27;monkeys&#x2F;_monkey.html.erb&#x27; partial, donkey with the &#x27;donkeys&#x2F;_donkey.html.erb&#x27; partial, and last but definitely not lest, dramatic_gopher with the &#x27;dramatic_chipmunks&#x2F;_dramatic_chipmunk.html.erb&#x27; partial&lt;&#x2F;p&gt;
&lt;p&gt;This is especially useful if when using &lt;acronym title=&quot;Single Table Inheritance&quot;&gt;STI&lt;&#x2F;acronym&gt;, where your ActiveRecord model would return objects of different types. The collection &lt;code&gt;[ monkey, donkey, dramatic_chipmunk ]&lt;&#x2F;code&gt; could very well be something returned from your &lt;code&gt;Animal&lt;&#x2F;code&gt; model that has subclasses of &lt;code&gt;Monkey&lt;&#x2F;code&gt;, &lt;code&gt;Donkey&lt;&#x2F;code&gt; and &lt;code&gt;DramaticChipmunk&lt;&#x2F;code&gt; via STI.&lt;&#x2F;p&gt;
&lt;p&gt;Credit: &lt;a href=&quot;http:&#x2F;&#x2F;www.continuousthinking.com&#x2F;&quot;&gt;Zach Dennis&lt;&#x2F;a&gt; of &lt;a href=&quot;http:&#x2F;&#x2F;www.continuousthinking.com&#x2F;tags&#x2F;arext&quot;&gt;ar-extensions&lt;&#x2F;a&gt; fame.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9177&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9177&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveModel work revived&lt;&#x2F;h3&gt;
&lt;p&gt;It seems like work on ActiveModel (think unified ActiveRecord and ActiveResource behaviors) has been revived, if the latest commits (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9171&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9171&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9173&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9173&lt;&#x2F;a&gt;) by David (DHH) is anything to go by.&lt;&#x2F;p&gt;
&lt;h3&gt;Bugfix: Assigning an invalid has_one association now causes #save to fail on parent&lt;&#x2F;h3&gt;
&lt;p&gt;You could do this before:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;firm = Firm.find(:first)
firm.account = Account.new # Associate INVALID account
firm.save # This doesn&#x27;t fail&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that&#x27;s fixed thanks to &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;Pratik Naik&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9232&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9232&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As usual, any feedback is respectfully appreciated!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #14 - the extreme edition. Extremely late.</title>
    <published>2008-04-05T00:04:06+00:00</published>
    <updated>2008-04-05T00:04:06+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/"/>
    <id>https://chuyeow.wtf/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/">&lt;p&gt;This week’s report covers changes from 24 Mar 2008 to 30 Mar 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;re lots of big exciting changes this week on edge. Smells like 2.1 soon!&lt;&#x2F;p&gt;
&lt;h3&gt;has_finder gem merged into Rails&lt;&#x2F;h3&gt;
&lt;p&gt;Ryan Daigle has &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2008&#x2F;3&#x2F;24&#x2F;what-s-new-in-edge-rails-has-finder-functionality&quot;&gt;the scoop on the new has_finder-like functionality in Rails&lt;&#x2F;a&gt; so head on over (I won&#x27;t repeat it here in the interests of &lt;acronym title=&quot;Don&#x27;t Repeat Yourself&quot;&gt;DRY&lt;&#x2F;acronym&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;pivots.pivotallabs.com&#x2F;users&#x2F;nick&#x2F;blog&#x2F;articles&#x2F;284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries&quot;&gt;Nick Kallen&lt;&#x2F;a&gt; for coming up with the has_finder gem.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9084&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9084&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord: Unsaved attribute changes are now tracked&lt;&#x2F;h3&gt;
&lt;p&gt;You can now ask an ActiveRecord model whether its attributes have been changed (and is unsaved) using the &lt;code&gt;{attr_name}_changed?&lt;&#x2F;code&gt; (magic) method. The &lt;code&gt;{attr_name}_was&lt;&#x2F;code&gt; method will return the original value of the attribute, and the &lt;code&gt;{attr_name}_change&lt;&#x2F;code&gt; method will return an array with 2 members, the 1st being the original value, the 2nd being the changed (and unsaved) value.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# Change person&#x27;s name.
person.name = &#x27;Jason Seifer&#x27;
person.changed?       # =&gt; true
person.name_changed?  # =&gt; true
person.name_was       # =&gt; &#x27;jseifer&#x27;
person.name_change    # =&gt; [&#x27;jseifer&#x27;, &#x27;Jason Seifer&#x27;]
person.name = &#x27;Ceiling Cat&#x27;
person.name_change    # =&gt; [&#x27;jseifer&#x27;, &#x27;Ceiling Cat&#x27;]&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to Rails core team member Jeremy Kemper (bitsweat) for this patch (which originated from Jeremy&#x27;s very own &lt;a href=&quot;http:&#x2F;&#x2F;code.bitsweat.net&#x2F;svn&#x2F;dirty&quot;&gt;Dirty plugin&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9127&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9127&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord#Base.all&#x2F;first&#x2F;last&lt;&#x2F;h3&gt;
&lt;p&gt;Now you can do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Post.all.each { |post| # something }
Post.first
Post.last&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Kinda like how some other ORMs do (like DataMapper).&lt;&#x2F;p&gt;
&lt;p&gt;Credit: &lt;a href=&quot;http:&#x2F;&#x2F;www.thechrisoshow.com&#x2F;&quot;&gt;thechrisoshow&lt;&#x2F;a&gt; and again, Nick Kallen for has_finder.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9085&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9085&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Timestamped Migrations&lt;&#x2F;h3&gt;
&lt;p&gt;This is more useful than it sounds: migrations are now timestamped instead of using incremental numbers in your db&#x2F;migrate folder. This eliminates the problem of migrations having the same version number when working on a multi-developer Rails app.&lt;&#x2F;p&gt;
&lt;p&gt;Two new Rake tasks, rake &lt;code&gt;db:migrate:up&#x2F;down&lt;&#x2F;code&gt;, have been added to allow running of the &lt;code&gt;up&lt;&#x2F;code&gt; and &lt;code&gt;down&lt;&#x2F;code&gt; methods of individual migrations.&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to John Barnette, the guy who gave you &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2007&#x2F;10&#x2F;26&#x2F;what-s-new-in-edge-rails-fixtures-just-got-a-whole-lot-easier&quot;&gt;foxy fixtures&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset:&lt;a href=&quot; http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9122&quot;&gt; http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9122&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;New config.gem option for specifying which gems are required by the application + rake tasks for installing and freezing gems&lt;&#x2F;h3&gt;
&lt;p&gt;Specify which gems are required by your Rails app in your Rails &lt;code&gt;environment.rb&lt;&#x2F;code&gt;! &quot;Vendor everything&quot; supported right in Rails :). An example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Rails::Initializer.run do |config| 
  config.gems &#x27;chronic&#x27;
  config.gems &quot;hpricot&quot;, :version =&gt; &#x27;0.6&#x27;, :source =&gt; &quot;http:&#x2F;&#x2F;code.whytheluckystiff.net&quot;
  config.gems &quot;aws-s3&quot;, :lib =&gt; &quot;aws&#x2F;s3&quot;
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are also new Rake tasks:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# List required gems. 
rake gems 
&lt;h1 id=&quot;install-all-required-gems&quot;&gt;Install all required gems:&lt;&#x2F;h1&gt;
&lt;p&gt;rake gems:install&lt;&#x2F;p&gt;
&lt;h1 id=&quot;unpack-specified-gem-to-vendor-gems-gem-name-x-x-x&quot;&gt;Unpack specified gem to vendor&#x2F;gems&#x2F;gem_name-x.x.x&lt;&#x2F;h1&gt;
&lt;p&gt;rake gems:unpack GEM=chronic&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to the prolific &lt;a href=&quot;http:&#x2F;&#x2F;techno-weenie.net&#x2F;&quot;&gt;Rick Olson&lt;&#x2F;a&gt; for this gem of a patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9140&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9140&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveResource #clone&lt;&#x2F;h3&gt;
&lt;p&gt;You can now clone an existing resource:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;gregg = Person.find(1)
borg = gregg.clone&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This doesn&#x27;t clone child ActiveResource members though, just the straight up attributes of resource.&lt;&#x2F;p&gt;
&lt;p&gt;Contribors: &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;&quot;&gt;Ryan Daigle&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.thechrisoshow.com&#x2F;&quot;&gt;thechrisoshow&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9121&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9121&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Big documentation patch&lt;&#x2F;h3&gt;
&lt;p&gt;A big doc patch consisting of all the efforts going on in the &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;lifo&#x2F;doc-rails&#x2F;&quot;&gt;doc-rails repository on Github&lt;&#x2F;a&gt; has been committed. Check out &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;rubyonrails-core&#x2F;browse_thread&#x2F;thread&#x2F;92f822141df3c217&#x2F;71e7460d41bdfd89&quot;&gt;Pratik&#x27;s post&lt;&#x2F;a&gt; for more info on what doc-rails is. Though with Rails moving to Git soon, doc-rails may no longer be necessary!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9093&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9093&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Installing libmemcached and memcached gem on Ubuntu</title>
    <published>2008-03-31T12:20:54+00:00</published>
    <updated>2008-03-31T12:20:54+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/31/installing-libmemcached-and-memcached-gem-on-ubuntu/"/>
    <id>https://chuyeow.wtf/2008/03/31/installing-libmemcached-and-memcached-gem-on-ubuntu/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/31/installing-libmemcached-and-memcached-gem-on-ubuntu/">&lt;p&gt;Quick notes for installing &lt;a href=&quot;http:&#x2F;&#x2F;tangent.org&#x2F;552&#x2F;libmemcached.html&quot;&gt;libmemcached&lt;&#x2F;a&gt; and Evan Weaver&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;blog.evanweaver.com&#x2F;files&#x2F;doc&#x2F;fauna&#x2F;memcached&#x2F;files&#x2F;README.html&quot;&gt;memcached gem&lt;&#x2F;a&gt;, in case I forget (again):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Get libmemcached source from &lt;a href=&quot;http:&#x2F;&#x2F;tangent.org&#x2F;552&#x2F;libmemcached.html&quot;&gt;http:&#x2F;&#x2F;tangent.org&#x2F;552&#x2F;libmemcached.html&lt;&#x2F;a&gt;. Configure, make, make install. Make sure you get a version compatible with the Ruby memcached gem by opening the COMPATIBILITY file in the memcached gem files.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gem install memcached&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Create a symlink &lt;code&gt;ln -s &#x2F;usr&#x2F;local&#x2F;lib&#x2F;libmemcached.so.2 &#x2F;usr&#x2F;lib&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Try it out with &lt;code&gt;irb -rubygems&lt;&#x2F;code&gt;, &lt;code&gt;require &#x27;memcached&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #13 - Git script&#x2F;plugin install, has_one :through</title>
    <published>2008-03-27T23:46:34+00:00</published>
    <updated>2008-03-27T23:46:34+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/"/>
    <id>https://chuyeow.wtf/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/">&lt;p&gt;It&#x27;s time again for some edge Rails love. If you haven&#x27;t listened to it yet, be sure to check out &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;3&#x2F;26&#x2F;rails-envy-podcast-episode-024-03-26-2008&quot;&gt;this week&#x27;s Rails Envy podcast&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 17 Mar 2008 to 23 Mar 2008 (the day the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;3&#x2F;26&#x2F;rails-envy-podcast-episode-024-03-26-2008&quot;&gt;corresponding Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;script&#x2F;plugin install works for Git repositories&lt;&#x2F;h3&gt;
&lt;p&gt;Yup you can now install plugins from &lt;a href=&quot;http:&#x2F;&#x2F;git.or.cz&#x2F;&quot;&gt;Git&lt;&#x2F;a&gt; repositories simply by running:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;script&#x2F;plugin install git:&#x2F;&#x2F;github.com&#x2F;foo&#x2F;kung_fu&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;What this really does is to clone a git repository (sans the entire git history by passing the &lt;code&gt;—depth 1&lt;&#x2F;code&gt; option) into your plugins directory. If you&#x27;re looking for a Piston-like way to manage external Git repositories though, you&#x27;d still be better off with the development version of &lt;a href=&quot;http:&#x2F;&#x2F;piston.rubyforge.org&#x2F;&quot;&gt;Piston&lt;&#x2F;a&gt; (François Beausoleil, is &lt;a href=&quot;http:&#x2F;&#x2F;blog.teksol.info&#x2F;tags&#x2F;piston&quot;&gt;posting frequently on his progress with adding Git support&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;6brand.com&#x2F;git-svn-externals-rails-plugins&quot;&gt;Jack Danger&lt;&#x2F;a&gt;, a long-time Rails contributor for this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9049&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9049&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;has_one :through&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s been a long time coming - now you can do &lt;code&gt;has_one :through&lt;&#x2F;code&gt; (like &lt;code&gt;has_many :through&lt;&#x2F;code&gt;) for your join models. &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;&quot;&gt;Ryan Daigle&lt;&#x2F;a&gt; has &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2008&#x2F;3&#x2F;24&#x2F;what-s-new-in-edge-rails-has-one-through&quot;&gt;example code&lt;&#x2F;a&gt; on how to use it if you&#x27;re curious (though really, it&#x27;s just like has_many).&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to the &lt;a href=&quot;http:&#x2F;&#x2F;artofmission.com&#x2F;&quot;&gt;Art of Mission&lt;&#x2F;a&gt; guys and &lt;a href=&quot;http:&#x2F;&#x2F;www.thechrisoshow.com&#x2F; http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;9008-chris-o-sullivan&quot;&gt;Chris O&#x27;Sullivan&lt;&#x2F;a&gt; for pulling it all together.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9067&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9067&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;rake tasks time:zones:all, time:zones:us and time:zones:local&lt;&#x2F;h3&gt;
&lt;p&gt;Some timezone-related rake tasks have been added to list the names of time zones recognized by the &lt;code&gt;TimeZone&lt;&#x2F;code&gt; class for the &lt;code&gt;config.time_zone&lt;&#x2F;code&gt; option you can put in your &lt;code&gt;environment.rb&lt;&#x2F;code&gt;. For example&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;rake time:zones:local&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;* UTC +08:00 *
Beijing
Chongqing
Hong Kong
Irkutsk
Kuala Lumpur
Perth
Singapore
Taipei
Ulaan Bataar
Urumqi&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit: Geoff Buesing (core team member)&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9074&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9074&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;#number_to_currency helper now supports a :format option&lt;&#x2F;h3&gt;
&lt;p&gt;Now you can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;number_to_currency(123.50, :unit =&gt; &quot;&amp;pound;&quot;, :format =&gt; &quot;%n %u&quot;) 
# =&gt; 123.50 &amp;pound;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instead of being stuck with the &lt;code&gt;{currency_code} {amount}&lt;&#x2F;code&gt; format which doesn&#x27;t work in some locales (such as &quot;42 pounds&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9052&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9052&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #12</title>
    <published>2008-03-20T20:19:18+00:00</published>
    <updated>2008-03-20T20:19:18+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/20/living-on-the-edge-of-rails-12/"/>
    <id>https://chuyeow.wtf/2008/03/20/living-on-the-edge-of-rails-12/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/20/living-on-the-edge-of-rails-12/">&lt;p&gt;This week’s report covers changes from 10 Mar 2008 to 16 Mar 2008 (the day the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;3&#x2F;19&#x2F;rails-envy-podcast-episode-023-03-19-2008&quot;&gt;corresponding Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Custom JavaScript and stylesheet symbols&lt;&#x2F;h3&gt;
&lt;p&gt;Remember how you can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;javascript_include_tag :defaults&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and Rails would load all the Prototype JavaScript files and your application.js?&lt;&#x2F;p&gt;
&lt;p&gt;You can now register your own custom expansion symbol too:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# In a Rails initializer.
ActionView::Helpers::AssetTagHelper.register_javascript_expansion :yui =&gt; [&#x27;yahoo&#x27;, &#x27;autocomplete&#x27;, &#x27;calendar&#x27;]
&lt;h1 id=&quot;in-your-view&quot;&gt;In your view.&lt;&#x2F;h1&gt;
&lt;p&gt;javascript_include_tag :yui&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;would result in:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;yahoo.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;
&amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;autocomplete.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;
&amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;calendar.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can do the same with the &lt;cpde&gt;stylesheet_link_tag&lt;&#x2F;cpde&gt; by registering a custom expansion symbol via &lt;code&gt;register_stylesheet_expansion&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is useful for anyone but in particular plugin developers who have a multiple asset files would appreciate being able to tell users to include JavaScript or stylesheets using a single symbol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;&#x2F;strong&gt;: This patch currently breaks the default symbols like &lt;code&gt;:all&lt;&#x2F;code&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10350&quot;&gt;check out the ticket&lt;&#x2F;a&gt; for more info).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9016&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9016&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Sexy default timestamps in migrations&lt;&#x2F;h3&gt;
&lt;p&gt;Remember how you can say &lt;code&gt;timestamps&lt;&#x2F;code&gt; in a migration and Rails will create the &#x27;created_at&#x27; and &#x27;updated_at&#x27; columns for you? You can now also do &lt;code&gt;add_timestamps :table_name&lt;&#x2F;code&gt; and &lt;code&gt;remove_timestamps :table_name&lt;&#x2F;code&gt; in your migrations if you decide to add these columns later to a table:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def self.up
  add_timestamps :posts
end
&lt;p&gt;def self.down
remove_timestamps :posts
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9014&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9014&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord::Base#find(:last)&lt;&#x2F;h3&gt;
&lt;p&gt;Just like &lt;code&gt;Comment.find(:first)&lt;&#x2F;code&gt;, you can now do something like &lt;code&gt;Comment.find(:last)&lt;&#x2F;code&gt;. There&#x27;s some controversy over whether this is bloat, but &lt;acronym title=&quot;David Heinemeier Hansson&quot;&gt;DHH&lt;&#x2F;acronym&gt; makes a good case for it with this example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Person
  has_many :comments, :order =&amp;gt; &#x27;created_at&#x27;
end
&lt;p&gt;@some_person.comments.find(:last) # =&amp;gt; Returns the most recent comment.&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9012&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9012&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Database rake tasks fixes&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;rake db:create&lt;&#x2F;code&gt; used to ignore the &#x27;charset&#x27; and &#x27;collation&#x27; options in your database.yml configuration file. This has been fixed so that your created databases now respect those options.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;rake db:drop&lt;&#x2F;code&gt; and &lt;code&gt;rake db:migrate:reset&lt;&#x2F;code&gt; also no longer crash with an unhelpful exception if the database has already been dropped, and instead shows a proper error message.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9004&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9004&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Rails&#x27; logger now creates the log directory if it doesn&#x27;t exist&lt;&#x2F;h3&gt;
&lt;p&gt;This is a blessing to those of us who use version control systems that don&#x27;t support empty directories (like Git). Rails&#x27; default logger (the BufferedLogger), now creates a log&#x2F; directory if it doesn&#x27;t already exist. This should save you the step of creating&#x2F;symlinking a log&#x2F; directory (or symlinking) on deploy.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9013&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9013&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;String#squish is faster&lt;&#x2F;h3&gt;
&lt;p&gt;A faster implementation of the &lt;code&gt;String#squish&lt;&#x2F;code&gt; (and &lt;code&gt;String#squish!&lt;&#x2F;code&gt;) core extension has been committed.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9015&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9015&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;The #excerpt TextHelper no longer includes 1 character too many&lt;&#x2F;h3&gt;
&lt;p&gt;Turns out that the &lt;code&gt;#excerpt&lt;&#x2F;code&gt; helper method was consistently including an extra character. This has been fixed.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9030&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;9030&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As usual, let me know of any inaccuracies or any suggestions you may have in the comments!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>UTF8 encoding with Ruby Sequel (and MySQL)</title>
    <published>2008-03-15T23:12:17+00:00</published>
    <updated>2008-03-15T23:12:17+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/15/utf8-encoding-with-ruby-sequel-and-mysql/"/>
    <id>https://chuyeow.wtf/2008/03/15/utf8-encoding-with-ruby-sequel-and-mysql/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/15/utf8-encoding-with-ruby-sequel-and-mysql/">&lt;p&gt;Just a quick note to self. If you need to store Unicode and are using &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;ruby-sequel&#x2F;&quot;&gt;Sequel&lt;&#x2F;a&gt;, make sure you:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Create the database with a default charset of UTF8: &lt;code&gt;CREATE DATABASE my_db DEFAULT CHARSET utf8;&lt;&#x2F;code&gt;. I think then any tables you create uses the default charset of utf8 unless &lt;a href=&quot;http:&#x2F;&#x2F;dev.mysql.com&#x2F;doc&#x2F;refman&#x2F;5.0&#x2F;en&#x2F;create-table.html&quot;&gt;otherwise specified&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Pass an &lt;code&gt;:encoding&lt;&#x2F;code&gt; option to Sequel&#x27;s MySQL adapter:
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;DB = Sequel.mysql &#x27;my_db&#x27;, :user =&amp;gt; &#x27;root&#x27;, :password =&amp;gt; &#x27;&#x27;, :host =&amp;gt; &#x27;localhost&#x27;, :encoding =&amp;gt; &#x27;utf8&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;sequel.rubyforge.org&#x2F;files&#x2F;sequel&#x2F;README.html&quot;&gt;Sequel documentation&lt;&#x2F;a&gt; and wiki were quite unhelpful but &lt;a href=&quot;http:&#x2F;&#x2F;ruby-sequel.googlecode.com&#x2F;svn&#x2F;trunk&#x2F;sequel_core&#x2F;lib&#x2F;sequel_core&#x2F;adapters&#x2F;mysql.rb&quot;&gt;reading code&lt;&#x2F;a&gt; (see the &lt;code&gt;connect&lt;&#x2F;code&gt; method definition) always helps!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #11</title>
    <published>2008-03-12T19:39:17+00:00</published>
    <updated>2008-03-12T19:39:17+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/12/living-on-the-edge-of-rails-11/"/>
    <id>https://chuyeow.wtf/2008/03/12/living-on-the-edge-of-rails-11/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/12/living-on-the-edge-of-rails-11/">&lt;p&gt;This week’s report covers changes from 3 Mar 2008 to 9 Mar 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Improve performance on :include&#x2F;:conditions&#x2F;:limit queries by selectively joining in the pre-query&lt;&#x2F;h3&gt;
&lt;p&gt;This is another ActiveRecord performance boost related to the pre-loading any eager-loaded &lt;code&gt;:includes&lt;&#x2F;code&gt; &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;01&#x2F;30&#x2F;living-on-the-edge-of-rails-5-better-eager-loading-and-more&#x2F;&quot;&gt;mentioned previously&lt;&#x2F;a&gt;. Basically what this patch does is to only join referenced tables when needed. It does this by checking the &lt;code&gt;:conditions&lt;&#x2F;code&gt; and &lt;code&gt;:limit&lt;&#x2F;code&gt; options to determine whether a table should be joined or can be left out and pre-loaded instead. You can find out more in tickets &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9560&quot;&gt;#9560&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9497&quot;&gt;#9497&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;8164-gabe-da-silveira&quot;&gt; Gabe da Silveira&lt;&#x2F;a&gt; (dasil003 on Trac) for this awesome performance patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8977&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8977&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Better error message for type errors when parsing request parameters&lt;&#x2F;h3&gt;
&lt;p&gt;Now when you pass an incorrectly formed request (e.g. GET, POST) parameter to your controller, it will raise an exception that includes a friendlier error message that indicates exactly what you passed to it. This is helpful when trying to debug whether you constructed your form correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Contributors: &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;5519-chad-humphries&quot;&gt;Chad Humphries&lt;&#x2F;a&gt; and matt.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8986&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8986&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Make MimeResponds::Responder#any work without explicit types.&lt;&#x2F;h3&gt;
&lt;p&gt;Here&#x27;s something I didn&#x27;t know: you can actually use &lt;code&gt;any&lt;&#x2F;code&gt; in your &lt;code&gt;respond_to&lt;&#x2F;code&gt; blocks as a catch-all response. E.g.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;respond_to do |format|
  format.html do
    redirect_to :action =&amp;gt; &#x27;login&#x27;
  end
  format.any(:js, :xml) do
    request_http_basic_authentication &#x27;Web Password&#x27;
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Contrary to its name, using &#x27;any&#x27; actually requires you to pass a list of types to respond to. This has been enhanced now so that if you don&#x27;t pass any arguments, it&#x27;ll function as a real catch-all.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;respond_to do |format|
  format.any do
    request_http_basic_authentication &#x27;Web Password&#x27;
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;3231-joshua-wehner&quot;&gt;Joshua Wehner&lt;&#x2F;a&gt; for this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8987&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8987&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Add readonly option to has_many :through associations&lt;&#x2F;h3&gt;
&lt;p&gt;Turns out the &lt;code&gt;:readonly&lt;&#x2F;code&gt; option for associations &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2008&#x2F;02&#x2F;19&#x2F;living-on-the-edge-of-rails-8-the-code-optimization-edition&#x2F;&quot;&gt;mentioned earlier&lt;&#x2F;a&gt; was left out for &lt;code&gt;has_many :through&lt;&#x2F;code&gt; associations. This oversight has been fixed.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;9147-emilio-tagua&quot;&gt;Emilio Tagua&lt;&#x2F;a&gt; for this bugfix.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8989&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8989&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As usual, let me know of any inaccuracies or any suggestions you may have in the comments!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #10</title>
    <published>2008-03-05T20:01:32+00:00</published>
    <updated>2008-03-05T20:01:32+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/03/05/living-on-the-edge-of-rails-10/"/>
    <id>https://chuyeow.wtf/2008/03/05/living-on-the-edge-of-rails-10/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/03/05/living-on-the-edge-of-rails-10/">&lt;p&gt;Another awfully sleepy week on Rails edge. Though by the time I had sent over the notes to Gregg Pollack and Jason Seifer of the awesome &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt;, there has been some nice changes (that I&#x27;ll be mentioning next week, but there&#x27;s absolutely nothing stopping you from &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;timeline?changeset=on&quot;&gt;checking those out yourself&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;In other interesting news, &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;Pratik Naik&lt;&#x2F;a&gt; (lifofifo), a long-time Rails contributor has been given commit rights to Rails. Congrats Pratik, well-deserved and it has been long overdue in my opinion! Pratik keeps an interesting blog at &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;http:&#x2F;&#x2F;m.onkey.org&#x2F;&lt;&#x2F;a&gt; (where he&#x27;s not afraid to say &quot;fuck&quot; in his posts &lt;em&gt;and&lt;&#x2F;em&gt; his code) and hangs out an awful lot on &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rubyonrails&quot;&gt;#rubyonrails&lt;&#x2F;a&gt; and &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rails-contrib&quot;&gt;#rails-contrib&lt;&#x2F;a&gt; on IRC.&lt;&#x2F;p&gt;
&lt;p&gt;As a sidenote, &lt;a href=&quot;http:&#x2F;&#x2F;weblog.jamisbuck.org&#x2F;2008&#x2F;2&#x2F;28&#x2F;capistrano-2-2-0&quot;&gt;Capistrano 2.2.0 was released&lt;&#x2F;a&gt; by &lt;a href=&quot;http:&#x2F;&#x2F;weblog.jamisbuck.org&#x2F;&quot;&gt;Jamis&lt;&#x2F;a&gt; last week.&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 25 Feb 2008 to 2 Mar 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Time#end_of_XXX methods&lt;&#x2F;h3&gt;
&lt;p&gt;A bunch of Time core extension methods have been added. These are: &lt;code&gt;Time#end_of_day&lt;&#x2F;code&gt;, &lt;code&gt;Time#end_of_week&lt;&#x2F;code&gt;, &lt;code&gt;Time#end_of_year&lt;&#x2F;code&gt;, and &lt;code&gt;Time#end_of_quarter&lt;&#x2F;code&gt;, which all return exactly what you expect them to return:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Time.now.end_of_week # =&amp;gt; Sun Mar 09 00:00:00 0800 2008&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Credit goes to &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;5065-juanjo-baz-n&quot;&gt;Juanjo Bazán&lt;&#x2F;a&gt; (a former &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2007&#x2F;10&#x2F;22&#x2F;hackfest-winner-interview-juanjo-bazn&quot;&gt;Rails Hackfest winner&lt;&#x2F;a&gt;) and &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;7168-tarmo-t-nav&quot;&gt;Tarmo Tänav&lt;&#x2F;a&gt; for contributing this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8934&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8934&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Date helpers now accept HTML options&lt;&#x2F;h3&gt;
&lt;p&gt;ActionView&#x27;s date helpers (such as &lt;code&gt;date_select&lt;&#x2F;code&gt;, &lt;code&gt;time_select&lt;&#x2F;code&gt;, &lt;code&gt;select_datetime&lt;&#x2F;code&gt;) did not support any HTML options, unlike the other helpers (like &lt;code&gt;f.text_field(:name, :class =&gt; &#x27;my_css_class&#x27;, :size =&gt; 20)&lt;&#x2F;code&gt;). This inconsistency has been fixed and you can now finally do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;%= date_select &#x27;user&#x27;, &#x27;birthday&#x27;, :order =&amp;gt; [:day], :class =&amp;gt; &#x27;my_css_class&#x27; %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;5430-murray-steele&quot;&gt;Murray Steele&lt;&#x2F;a&gt; (h-lame on the Rails Trac) and &lt;a hre=&quot;http:&#x2F;&#x2F;mentalized.net&#x2F;&quot;&gt;Jakob Skjerning&lt;&#x2F;a&gt; contributed this patch.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8968&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8968&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;No need for explicit respond_to for RJS templates&lt;&#x2F;h3&gt;
&lt;p&gt;ActionController has been changed so that JS requests will automatically render action.js.rjs files without the need to specify an explicit &lt;code&gt;respond_to&lt;&#x2F;code&gt; block. This means that your .rjs files work the same way as your .html.erb files - just put them in the right place and Rails will use it.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8956&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8956&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Bugfixes&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8937 - Prevent Rails from crashing when trying to deserialize an XML representation of a model named &quot;Type&quot; (using Hash#from_xml). Contributed by &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;5065-juanjo-baz-n&quot;&gt;Juanjo Bazán&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;7102-isaac-feliu&quot;&gt;Isaac Feliu&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8942 - Fix eager loading so that it doesn&#x27;t pull in duplicate records in some cases. Contributed by Catfish.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As usual, let me know of any inaccuracies or any suggestions you may have in the comments!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #9 - the sleeper edition</title>
    <published>2008-02-27T09:56:49+00:00</published>
    <updated>2008-02-27T09:56:49+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/02/27/living-on-the-edge-of-rails-9-the-sleeper-edition/"/>
    <id>https://chuyeow.wtf/2008/02/27/living-on-the-edge-of-rails-9-the-sleeper-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/02/27/living-on-the-edge-of-rails-9-the-sleeper-edition/">&lt;p&gt;It&#x27;s been a slow week on the Rails trunk this week in terms of exciting changes.&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 18 Feb 2008 to 24 Feb 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveResource::Base now accepts user and password configuration&lt;&#x2F;h3&gt;
&lt;p&gt;You can now set the user and password for HTTP authentication in your ActiveResource models:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Person &lt; ActiveResource::Base
  self.site = &#x27;http:&#x2F;&#x2F;example.com&#x2F;&#x27;
  self.user = &#x27;konata&#x27;
  self.password = &#x27;password&#x27;
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a better way to specify authentication credentials than the current way of doing it by putting it all in the site (e.g. &lt;code&gt;self.site = &#x27;http:&#x2F;&#x2F;konata:password@example.com&#x2F;&#x27;&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8891&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8891&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;script&#x2F;plugin install now supports SVN export&lt;&#x2F;h3&gt;
&lt;p&gt;You can now pass the &lt;code&gt;-e&#x2F;--export&lt;&#x2F;code&gt; option to &lt;code&gt;script&#x2F;plugin install&lt;&#x2F;code&gt; to do an Subversion export of the plugin. This allows you to then check in the plugin&#x27;s files into your own repository. Though seriously, if anyone really wants to do this, I&#x27;d suggest they use &lt;a href=&quot;http:&#x2F;&#x2F;piston.rubyforge.org&#x2F;&quot;&gt;Piston&lt;&#x2F;a&gt;. That is, for those of us still using Subversion rather than Git.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8921&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8921&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Bug fixes for associations preloading&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;ve been some bug fixes the associations preloading change mentioned in &lt;a href=&quot;&#x2F;2008&#x2F;01&#x2F;30&#x2F;living-on-the-edge-of-rails-5-better-eager-loading-and-more&#x2F;&quot;&gt;Living on the edge #5&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8894&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8894&lt;&#x2F;a&gt; - Fixed a bug where associations that were preloaded (using nested &lt;code&gt;:includes&lt;&#x2F;code&gt;) errors out when the associations return &lt;code&gt;nil&lt;&#x2F;code&gt; (i.e. when there are no associated records).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;11154&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;11154&lt;&#x2F;a&gt; - Fixed a bug where nested includes were assuming that all records are from the same class. This is not true for polymorphic associations, causing problems when they were being used.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Yup, that&#x27;s it for this week. As usual, let me know of anything I might have missed or any suggestions you may have in the comments!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #8 - the code optimization edition</title>
    <published>2008-02-19T23:30:54+00:00</published>
    <updated>2008-02-19T23:30:54+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/02/19/living-on-the-edge-of-rails-8-the-code-optimization-edition/"/>
    <id>https://chuyeow.wtf/2008/02/19/living-on-the-edge-of-rails-8-the-code-optimization-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/02/19/living-on-the-edge-of-rails-8-the-code-optimization-edition/">&lt;p&gt;Here&#x27;s this week&#x27;s update of the important changes that have been happening on edge Rails. There were lots of performance patches this week, credit mostly due to the guys from &lt;a href=&quot;http:&#x2F;&#x2F;www.acunote.com&#x2F;&quot;&gt;Acunote&lt;&#x2F;a&gt; and their latest &lt;a href=&quot;http:&#x2F;&#x2F;blog.pluron.com&#x2F;2008&#x2F;02&#x2F;rails-faster-as.html&quot;&gt;blog post on optimizing Rails&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 11 Feb 2008 to 17 Feb 2008 (the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord::Base#attributes-related optimizations&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ActiveRecord::Base#attributes_before_typecast&lt;&#x2F;code&gt; no longer clones attribute unnecessarily.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8858&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8858&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; now no longer supports options. The &lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; method used to support &lt;code&gt;:only&lt;&#x2F;code&gt; and &lt;code&gt;:except&lt;&#x2F;code&gt; options, which are actually unnecessary since it returns a Hash. You can use &lt;code&gt;Hash#slice&lt;&#x2F;code&gt; or &lt;code&gt;Hash#except&lt;&#x2F;code&gt; (both ActiveSupport core extensions) directly on the hash.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8863&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8863&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord associations optimized by avoiding named block arguments&lt;&#x2F;h3&gt;
&lt;p&gt;Alexander Dymo is at it again optimizing ActiveRecord performance, this time by avoiding passing named block arguments. Turns out that it is faster and more memory efficient in Ruby to pass blocks like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def foo
  bar { |*block_args| yield(*block_args) if block_given?
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;instead of passing the block around like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def foo(&amp;&amp;amp;block)
  bar(&amp;amp;block)
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Occurrences of the more expensive way of passing blocks have been replaced in the ActiveRecord associations code so associations are lighter to use.&lt;&#x2F;p&gt;
&lt;p&gt;For a more detailed write-up, check out &lt;a href=&quot;http:&#x2F;&#x2F;blog.pluron.com&#x2F;2008&#x2F;02&#x2F;rails-faster-as.html&quot;&gt;Alexander&#x27;s blog entry&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8865&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8865&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord associations optimized by using symbol callbacks instead of string callbacks&lt;&#x2F;h3&gt;
&lt;p&gt;Again from Alexander Dymo, this patch also improving ActiveRecord association performance. Internally, ActiveRecord associations code uses a lot of string callbacks (e.g. &lt;code&gt;before_save &quot;some_ruby_code_to_eval&quot;&lt;&#x2F;code&gt;). It turns out that that is significantly more expensive compared to simply using &lt;code&gt;Module#define_method&lt;&#x2F;code&gt; because when the callback string is evaluated, the binding needs to be passed along. Passing the binding takes up memory (which is bad, of course).&lt;&#x2F;p&gt;
&lt;p&gt;The internal associations code has been changed to use that &lt;code&gt;define_method&lt;&#x2F;code&gt; now, and if you&#x27;re using a lot of associations, you would save megabytes of memory! (&lt;a href=&quot;http:&#x2F;&#x2F;blog.pluron.com&#x2F;2008&#x2F;02&#x2F;rails-faster-as.html&quot;&gt;Alexander&#x27;s blog post&lt;&#x2F;a&gt; has more detailed benchmarks.)&lt;&#x2F;p&gt;
&lt;p&gt;Remember, when writing your own before and after filters, not to use a string that needs to be &lt;code&gt;eval&lt;&#x2F;code&gt;ed!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8867&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8867&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Improve ActiveRecord::Base#save performance by avoiding repeated calls to ActiveRecord::Base#connection&lt;&#x2F;h3&gt;
&lt;p&gt;Another Alexander Dymo performance patch. This particular patch improves performance by getting the connection object just once and calling it directly, instead of needlessly calling several times. This should improve &lt;code&gt;ActiveRecord::Base#save&lt;&#x2F;code&gt; performance.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8871&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8871&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord associations now support the :readonly option&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;ActiveRecord::Base#find&lt;&#x2F;code&gt; supports the &lt;code&gt;:readonly&lt;&#x2F;code&gt; option to retrieve records that were read-only (i.e. you couldn&#x27;t save them). Now you can do the same for associations, like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;has_many :comments, :readonly =&gt; true&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows you to protect associated records from being saved.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8864&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8864&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;String#squish and String#squish! to remove consecutive chunks of whitespace&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;String#squish&lt;&#x2F;code&gt; extension has been added that trims whitespace from both ends of a string, and compressing consecutive whitespace groups within the string into 1 space each.&lt;&#x2F;p&gt;
&lt;p&gt;For example,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;@description = %{ String#squish() allows me to write long strings
  inside my Ruby code, without having to worry about indentation,
  the page margin, spaces, tabs or newlines. &quot;double&quot; or &#x27;single&#x27;
  quotes are both fine, and #{interpolation} works. }.squish
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8878&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8878&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any inaccuracies or any suggestions you may have in the comments, see you guys next week!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #7 - improved ActiveRecord::Base#attributes, time zone support</title>
    <published>2008-02-13T23:49:44+00:00</published>
    <updated>2008-02-13T23:49:44+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/02/13/living-on-the-edge-of-rails-7-improved-activerecordbaseattributes-time-zone-support/"/>
    <id>https://chuyeow.wtf/2008/02/13/living-on-the-edge-of-rails-7-improved-activerecordbaseattributes-time-zone-support/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/02/13/living-on-the-edge-of-rails-7-improved-activerecordbaseattributes-time-zone-support/">&lt;p&gt;It&#x27;s that time of the week again (every Wednesday for the overly observant, coinciding with the release of the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;2&#x2F;13&#x2F;rails-envy-podcast-episode-018-2-13-2008&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt;) for some choice updates of what changes have been happening on edge Rails. This week&#x27;s report covers changes from 4 Feb 2008 to 10 Feb 2008 (the day the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;2&#x2F;13&#x2F;rails-envy-podcast-episode-018-2-13-2008&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;More efficent ActiveRecord::Base#attributes&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; returns a hash of all attributes with clones of their objects as values. This unnecessary cloning is expensive, and has now been removed. &lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; now returns a hash of &lt;em&gt;values&lt;&#x2F;em&gt; of the attributes.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to Juanjo Bazan, there have been 2 further patches (after the podcast was recorded) related &lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; that further improves ActiveRecord&#x27;s performance: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8858&quot;&gt;removal of cloning from &lt;code&gt;ActiveRecord::Base#attributes_before_typecast&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8863&quot;&gt;removing options (&lt;code&gt;:only&lt;&#x2F;code&gt; and &lt;code&gt;:except&lt;&#x2F;code&gt; options, specifically) from &lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8824&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8824&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveResouce::Base#exists? now uses HTTP HEAD instead of a GET&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;HTTP#Request_Methods&quot;&gt;HTTP HEAD&lt;&#x2F;a&gt; request is really all that is needed to check for existence (200 == exists, 404 == doesn&#x27;t exist). This has been changed to HEAD from a GET request, which is more efficient since all we retrieve are the HTTP headers and there&#x27;s no unnecessary instantiation of the ActiveResource object.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8827&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8827&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Time zone support for ActiveRecord, and config.time_zone property for specifying a default Time Zone&lt;&#x2F;h3&gt;
&lt;p&gt;ActiveRecord models now have time zone-aware attribute readers and writers. Times returned from ActiveRecord attribute readers now have a &lt;code&gt;time_zone&lt;&#x2F;code&gt; attribute themselves, allowing time zone-aware calculations.&lt;&#x2F;p&gt;
&lt;p&gt;You can now configure the default &lt;code&gt;Time.zone&lt;&#x2F;code&gt; value with &lt;code&gt;config.time_zone&lt;&#x2F;code&gt; in your &lt;code&gt;environment.rb&lt;&#x2F;code&gt;. Setting this will enable time zone-awareness for ActiveRecord models.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8806&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8806&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;A Template class has been introduced to ActionView&lt;&#x2F;h3&gt;
&lt;p&gt;As part of the ActionPack refactoring that&#x27;s still ongoing, a &lt;code&gt;ActionView::Template&lt;&#x2F;code&gt; class has been introduced to encapsulate all the data relevant to the currently rendered template. This is largely an internal refactoring so Rails users shouldn&#x27;t be affected.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8805&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8805&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Concrete sweeper classes&lt;&#x2F;h3&gt;
&lt;p&gt;You can now use an explicit class when declaring a cache_sweeper. E.g.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class ListsController &amp;lt; ApplicationController 
  caches_action :index, :show, :public, :feed 
  cache_sweeper Sweepers::List, :only =&amp;gt; [ :edit, :destroy, :share ] 
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8819&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8819&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any inaccuracies or any suggestions you may have in the comments - this week&#x27;s report is a little rushed because I&#x27;m a little late in posting it up!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #6 - better performance, Git support, and more</title>
    <published>2008-02-06T21:54:37+00:00</published>
    <updated>2008-02-06T21:54:37+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/02/06/living-on-the-edge-of-rails-6-better-performance-git-support-and-more/"/>
    <id>https://chuyeow.wtf/2008/02/06/living-on-the-edge-of-rails-6-better-performance-git-support-and-more/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/02/06/living-on-the-edge-of-rails-6-better-performance-git-support-and-more/">&lt;p&gt;Here&#x27;s another week of noteworthy updates on the Rails trunk. Thanks once again to the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; for featuring my updates, and even bigger thanks to the Rails contributors and committers who make things happen. This week&#x27;s Living on the Edge was covered in &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;2008&#x2F;2&#x2F;6&#x2F;ruby-on-rails-podcast&quot;&gt;Rails Envy podcast #17&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The company I work for, &lt;a href=&quot;http:&#x2F;&#x2F;bezurk.com&#x2F;&quot;&gt;Bezurk&lt;&#x2F;a&gt; (yeah we know some of you hate the name &quot;Bezurk&quot; - that&#x27;s going to change), is currently looking for a Ruby developer to join our ranks. This person will be working mainly on Ruby-based web development projects. As we all know, &quot;Rails doesn&#x27;t scale&quot; (delivered in Jason Seifer-style - meaning it&#x27;s just a joke!) so we&#x27;d love anyone who&#x27;s up for a challenge and who&#x27;s also willing to work outside the Rails comfort zone (our current favorite: &lt;a href=&quot;http:&#x2F;&#x2F;ramaze.net&#x2F;&quot;&gt;Ramaze&lt;&#x2F;a&gt;). Our Ruby team currently comprises 3 experienced developers and 1 up and coming Rubyist.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re active Open Source contributors (Arun released &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;activecouch&#x2F;&quot;&gt;ActiveCouch&lt;&#x2F;a&gt; recently), while I am a Rails contributor (I&#x27;m &#x27;chuyeow&#x27; on the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;&quot;&gt;Rails Trac&lt;&#x2F;a&gt;) myself.&lt;&#x2F;p&gt;
&lt;p&gt;If all this sounds interesting enough to you, do check out the &lt;a href=&quot;http:&#x2F;&#x2F;jobs.monster.com.sg&#x2F;details&#x2F;4917397.html&quot;&gt;full job description&lt;&#x2F;a&gt; and drop us an email. Yes, we&#x27;re serious when we said &quot;+1 for DotA&#x2F;Counterstrike skills)&quot;. There&#x27;s a catch though - you have to work on location at our office in Singapore.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, let&#x27;s get back on topic - this weeks’ report covers changes from 28 Jan 2008 to 3 Feb 2008 (the day the Rails Envy podcast was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Saving, creating and updating ActiveRecord objects is more efficient&lt;&#x2F;h3&gt;
&lt;p&gt;Thanks to Gleb Arshinov and Alexander Dymo with their &lt;a href=&quot;http:&#x2F;&#x2F;blog.pluron.com&#x2F;2008&#x2F;01&#x2F;ruby-on-rails-i.html&quot;&gt;blog post and patches about improving Rails performance&lt;&#x2F;a&gt; by approaching it via minimizing garbage collection, saving, creating, and updating ActiveRecord objects is now significantly more efficient.&lt;&#x2F;p&gt;
&lt;p&gt;The expensive &lt;code&gt;ActiveRecord::Base#attributes&lt;&#x2F;code&gt; method is no longer called internally, so there&#x27;s no unnecessary cloning of attribute values. Less memory usage means less garbage collection, which means better performance!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8770&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8770&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;SQL calls and rendering are faster&lt;&#x2F;h3&gt;
&lt;p&gt;This patch is courtesy of &lt;a href=&quot;http:&#x2F;&#x2F;blog.pluron.com&#x2F;2008&#x2F;01&#x2F;ruby-on-rails-i.html&quot;&gt;Gleb Arshinov and Alexander Dymo&lt;&#x2F;a&gt; too.&lt;&#x2F;p&gt;
&lt;p&gt;Rails surrounds every SQL call and &lt;code&gt;ActionView::Base#render&lt;&#x2F;code&gt; with the ruby method &lt;code&gt;Benchmark#realtime&lt;&#x2F;code&gt; so that it can print out some benchmarking numbers. &lt;code&gt;Benchmark#realtime&lt;&#x2F;code&gt; allocates an unnecessary 45k of memory per call (who knew!). This has been monkey patched in Rails to a leaner implementation, reducing memory usage and increasing performance.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8771&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8771&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;MySQL adapter slight optimization&lt;&#x2F;h3&gt;
&lt;p&gt;Table and column names in the MySQL adapter are now cached in instance variables, reducing memory allocations (and thus the need for &lt;acronym title=&quot;garbage collection&quot;&gt;GC&lt;&#x2F;acronym&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8794&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8794&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;script&#x2F;generate does Git!&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;script&#x2F;generate&lt;&#x2F;code&gt; now allows you to pass the &#x27;--git&#x27; (or &#x27;-g&#x27;) option to add the generated files to git (much like how you could do the same with Subversion with &#x27;-c&#x27; or &#x27;--svn&#x27;). This patch is the work of &lt;a href=&quot;http:&#x2F;&#x2F;blog.stevensoroka.ca&#x2F;&quot;&gt;Steven Soroka&lt;&#x2F;a&gt; so nice work Steven!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8772&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8772&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;map.resources :products, :as =&gt; &#x27;something_else&#x27;&lt;&#x2F;h3&gt;
&lt;p&gt;Here&#x27;s something that will make non-english Rails developers happy: you can now do, for example,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;map.resources :comments, :as =&gt; &#x27;comentarios&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;so that you can keep having your model names independent of what URLs you&#x27;d actually like to appear on the site.&lt;&#x2F;p&gt;
&lt;p&gt;The above &lt;code&gt;map.resources&lt;&#x2F;code&gt; means that you can keep your resource and model names in English (Comment), while having URLs like this: &#x2F;comentarios&#x2F;123.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8785&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8785&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;:index option for form_for and fields_for to simplify multi-model forms&lt;&#x2F;h3&gt;
&lt;p&gt;Inspired by a &lt;a href=&quot;http:&#x2F;&#x2F;railscasts.com&#x2F;episodes&#x2F;75&quot;&gt;Railscasts episode&lt;&#x2F;a&gt; where Ryan Bates mentions how ugly it is to have to pass &lt;code&gt;:index =&gt; nil&lt;&#x2F;code&gt; to prevent &lt;code&gt;#text_field&lt;&#x2F;code&gt; (and other form helpers) from inserting the model&#x27;s ID in the input name (e.g. project[task_attributes][123][name] when what you really want is project[task_attributes][][name]).&lt;&#x2F;p&gt;
&lt;p&gt;Meaning instead of&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% fields_for &quot;project[task_attributes][]&quot;, task do |f| %&amp;gt;
  &amp;lt;%= f.text_field :name, :index =&amp;gt; nil %&amp;gt;
  &amp;lt;%= f.hidden_field :id, :index =&amp;gt; nil %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;you can now do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% fields_for &quot;project[task_attributes][]&quot;, task, :index =&amp;gt; nil do |f| %&amp;gt;
  &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;%= f.hidden_field :id %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8786&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8786&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;No more emails in your production logs&lt;&#x2F;h3&gt;
&lt;p&gt;You&#x27;d probably have noticed that ActionMailer logs &lt;em&gt;entire&lt;&#x2F;em&gt; email messages in the log, even in production. Well, it&#x27;s been changed to be less verbose now. At the &lt;code&gt;:info&lt;&#x2F;code&gt; log level, only the recipients are logged. You can still see the entire email at the &lt;code&gt;:debug&lt;&#x2F;code&gt; log level (which is the default for development environment).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8781&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8781&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, let me know of any inaccuracies or any suggestions you may have in the comments. Oh, and if you liked this, do me a favor by &lt;a href=&quot;http:&#x2F;&#x2F;reddit.com&#x2F;r&#x2F;ruby&#x2F;submit&quot;&gt;submitting it to Ruby Reddit&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>ActiveCouch - a CouchDB library in the spirit of ActiveResource and ActiveRecord</title>
    <published>2008-02-02T14:25:48+00:00</published>
    <updated>2008-02-02T14:25:48+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/02/02/activecouch-a-couchdb-library-in-the-spirit-of-activeresource-and-activerecord/"/>
    <id>https://chuyeow.wtf/2008/02/02/activecouch-a-couchdb-library-in-the-spirit-of-activeresource-and-activerecord/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/02/02/activecouch-a-couchdb-library-in-the-spirit-of-activeresource-and-activerecord/">&lt;p&gt;My fellow Rubyist at work, &lt;a href=&quot;http:&#x2F;&#x2F;arunthampi.wordpress.com&#x2F;&quot;&gt;Arun Thampi&lt;&#x2F;a&gt;, has released &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;activecouch&#x2F;&quot;&gt;ActiveCouch&lt;&#x2F;a&gt;, a Ruby library for &lt;a href=&quot;http:&#x2F;&#x2F;couchdb.org&#x2F;&quot;&gt;CouchDB&lt;&#x2F;a&gt; (if you don&#x27;t know what CouchDB is, &lt;a href=&quot;http:&#x2F;&#x2F;www.couchdbwiki.com&#x2F;index.php?title=CouchDb:About&quot;&gt;read this&lt;&#x2F;a&gt;). Check out the &lt;a href=&quot;http:&#x2F;&#x2F;blog.bezurk.com&#x2F;2008&#x2F;01&#x2F;23&#x2F;activecouch-a-ruby-wrapper-for-couchdb&#x2F;&quot;&gt;official blog announcement of ActiveCouch&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;ActiveCouch tries to be an ActiveResource and ActiveRecord (yes, there is even an &lt;code&gt;ActiveCouch::Migration&lt;&#x2F;code&gt; class for creating CouchDB views) equivalent for representing CouchDB documents in Ruby. I wish I could write some coherent code examples here but I am not that up to date with the latest changes in ActiveCouch (despite my name being tagged as a committer to ActiveCouch, it is largely &lt;a href=&quot;http:&#x2F;&#x2F;arunthampi.wordpress.com&#x2F;&quot;&gt;Arun&#x27;s&lt;&#x2F;a&gt; awesome little baby).&lt;&#x2F;p&gt;
&lt;p&gt;Never fear though, since Arun and I are chowing down our own dog food - we&#x27;re currently porting several gigabytes worth of hotel data from our hacked together XML and Ferret-based library to use the &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;activecouch&#x2F;&quot;&gt;ActiveCouch&lt;&#x2F;a&gt; library. I&#x27;m sure we&#x27;ll get a more coherent API after this exercise, since we are no longer relying on specs and mocks, but working on a Real Application.&lt;&#x2F;p&gt;
&lt;p&gt;If you decide to try out ActiveCouch, do let us know of any feedback or bug reports at the &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;activecouch&#x2F;&quot;&gt;ActiveCouch Google Code site&lt;&#x2F;a&gt;. ActiveCouch is Open Source, so if you&#x27;ve patches that&#x27;s even better!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #5 - better eager loading and more</title>
    <published>2008-01-30T18:26:39+00:00</published>
    <updated>2008-01-30T18:26:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/30/living-on-the-edge-of-rails-5-better-eager-loading-and-more/"/>
    <id>https://chuyeow.wtf/2008/01/30/living-on-the-edge-of-rails-5-better-eager-loading-and-more/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/30/living-on-the-edge-of-rails-5-better-eager-loading-and-more/">&lt;p&gt;Another week of edge Rails changes, featured on the &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;podcast&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt;. This weeks’ report covers changes from 21 Jan 2008 to 27 Jan 2008 (the day the &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;podcast&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Eager loading :includes does pre-loading&lt;&#x2F;h3&gt;
&lt;p&gt;The current gem Rails behavior when loading associations with something like&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Author.find(:all, :include =&gt; [:posts, :comments])&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;is to make a big query with multiple joins that fetches all the associations in the same query (for you RDBMS geeks, the &quot;cartesian product&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;Frederick Cheung (fcheung on the Rails Trac) has contributed an impressive optimization to this by pre-loading the associations rather than trying to eager loading with one big query. So a find like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Author.find(:all, :include =&gt; [:posts, :comments])&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;would first load all the authors, then all the posts, and then all the comments in 3 smaller, faster queries.&lt;&#x2F;p&gt;
&lt;p&gt;The main benefit of this (depending on your data): Running X simple queries (to fetch authors, then posts and comments) rather than one mega-query that joins all the associated tables is faster most of the time. The result set is often smaller as well.&lt;&#x2F;p&gt;
&lt;p&gt;More details can be found at &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9640&quot;&gt;ticket #9640 on the Rails Trac&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8672&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8672&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;&lt;code&gt;composed_of&lt;&#x2F;code&gt; aggregations can now be used in finder conditions&lt;&#x2F;h3&gt;
&lt;p&gt;You can now use value objects that you&#x27;ve previously specified that your model is &lt;code&gt;composed_of&lt;&#x2F;code&gt; in the finder conditions hash. E.g. if you have a Customer that has a balance aggregation:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Customer &amp;lt; ActiveRecord::Base
  composed_of :balance, :class_name =&amp;gt; &quot;Money&quot;, :mapping =&amp;gt; %w(balance amount)
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can now pass a Money value object to &lt;code&gt;Customer#find&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Customer.find(:all, :conditions =&amp;gt; { :balance =&amp;gt; Money.new(20, &quot;USD&quot;) })&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Convenient.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8671&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8671&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;New helper: label_tag&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;label_tag&lt;&#x2F;code&gt; helper has been missing for quite awhile since the label helper was added. No longer:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;label_tag &#x27;name&#x27;
# =&amp;gt; &amp;lt;label for=&quot;name&quot;&amp;gt;Name&amp;lt;&#x2F;label&amp;gt;
&lt;p&gt;label_tag &#x27;name&#x27;, &#x27;Your name&#x27;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;label-for-name-your-name-label&quot;&gt;=&amp;gt; &amp;lt;label for=&quot;name&quot;&amp;gt;Your name&amp;lt;&#x2F;label&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8685&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8685&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;New ActiveSupport class: ActiveSupport::TimeWithZone&lt;&#x2F;h3&gt;
&lt;p&gt;A new &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;time_with_zone.rb&quot;&gt;&lt;code&gt;ActiveSupport::TimeWithZone&lt;&#x2F;code&gt; class&lt;&#x2F;a&gt; has been introduced to make timezone support in Rails easier. Ryan Daigle has a &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2008&#x2F;1&#x2F;25&#x2F;what-s-new-in-edge-rails-easier-timezones&quot;&gt;good writeup&lt;&#x2F;a&gt; on this.&lt;&#x2F;p&gt;
&lt;p&gt;A word of warning though: this is still work in progress, as Geoff Buesing, the core team member responsible for these timezone changes, has more to add on how his &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2008&#x2F;1&#x2F;25&#x2F;what-s-new-in-edge-rails-easier-timezones#comment-6450&quot;&gt;plans for the timezone puzzle in the comments&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8696&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8696&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;map.root can be easily aliased&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;map.root&lt;&#x2F;code&gt; now accept a single symbol as an argument to declare an alias. Just a little something to keep your routes a little more DRY, e.g.:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;map.new_session :controller =&amp;gt; &#x27;sessions&#x27;, :action =&amp;gt; &#x27;new&#x27; 
map.root :new_session&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8738&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8738&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As usual, let me know of any inaccuracies or any suggestions you may have in the comments!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Trying code blocks in Ruby (aka Prototype&#x27;s Try.these)</title>
    <published>2008-01-28T23:30:50+00:00</published>
    <updated>2008-01-28T23:30:50+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/28/trying-code-blocks-in-ruby-aka-prototypes-trythese/"/>
    <id>https://chuyeow.wtf/2008/01/28/trying-code-blocks-in-ruby-aka-prototypes-trythese/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/28/trying-code-blocks-in-ruby-aka-prototypes-trythese/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;prototypejs.org&#x2F;api&#x2F;utility&#x2F;try-these&quot;&gt;Prototype&#x27;s &lt;code&gt;Try.these&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; is a really useful bit of code (though I doubt it sees much application outside of JavaScript libraries). I have this evil bit of code somewhere, for example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var results = Try.these(
  function() { return response.responseText.evalJSON(true); },
  function() { return eval(&#x27;(&#x27; + response.responseText + &#x27;)&#x27;); }
);&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Evilness personified in its &lt;code&gt;eval&lt;&#x2F;code&gt;ed glory, but that&#x27;s besides the point here.&lt;&#x2F;p&gt;
&lt;p&gt;Just for fun, I tried to do this in Ruby, just to see how easy it was, and came up with this &lt;code&gt;try&lt;&#x2F;code&gt; method:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;module Kernel
  def try(*these)
    raise ArgumentError, &#x27;try requires at least 2 arguments&#x27; if these.size &lt;= 1
    fallback = these.pop unless these.last.respond_to?(:call)
    these.each { |candidate| begin return candidate.call rescue next end }
    fallback || raise(RuntimeError, &#x27;None of the given procs succeeded&#x27;)
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which you can (ab)use like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;try(
  Proc.new { open(&#x27;http:&#x2F;&#x2F;finance.yahoo.com&#x2F;foo&#x2F;&#x27;) },
  lambda { open(&#x27;http:&#x2F;&#x2F;finance.google.com&#x2F;bar&#x2F;&#x27;) },
  proc { open(&#x27;http:&#x2F;&#x2F;finantiq.com&#x2F;flomp&#x2F;&#x27;) },
  :fallback
)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Real world applications would be, like the example above, retrieving content from several unreliable websites to retrieve currency rates.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the specs for &lt;code&gt;Kernel#try&lt;&#x2F;code&gt; here: &lt;a href=&quot;http:&#x2F;&#x2F;pastie.org&#x2F;144339&quot;&gt;http:&#x2F;&#x2F;pastie.org&#x2F;144339&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So the question now is, is there a better way to implement this, or a more idiomatic Ruby way?&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the edge (of Rails) #4 - faster routes, easier form partials</title>
    <published>2008-01-23T19:54:46+00:00</published>
    <updated>2008-01-23T19:54:46+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/23/living-on-the-edge-of-rails-4-faster-routes-easier-form-partials/"/>
    <id>https://chuyeow.wtf/2008/01/23/living-on-the-edge-of-rails-4-faster-routes-easier-form-partials/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/23/living-on-the-edge-of-rails-4-faster-routes-easier-form-partials/">&lt;p&gt;It&#x27;s time again for your weekly dose of what&#x27;s new in edge Rails. This weeks&#x27; report covers changes from 14 Jan 2008 to 20 Jan 2008 (the day the &lt;a href=&quot;http:&#x2F;&#x2F;railsenvy.com&#x2F;podcast&#x2F;&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded).&lt;&#x2F;p&gt;
&lt;h3&gt;Route recognition is faster&lt;&#x2F;h3&gt;
&lt;p&gt;Rails&#x27; route recognition has been optimized and is significantly faster especially for applications using many resources (i.e. via &lt;code&gt;map.resources&lt;&#x2F;code&gt; in your &lt;code&gt;config&#x2F;routes.rb&lt;&#x2F;code&gt;). Big thumbs up to Oleg Andreev (aka oleganza) who also &lt;a href=&quot;http:&#x2F;&#x2F;www.novemberain.com&#x2F;2008&#x2F;1&#x2F;17&#x2F;routes-recognition&quot;&gt;wrote a detailed post about it&lt;&#x2F;a&gt;. You can also find out more about how this works in the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;actionpack&#x2F;lib&#x2F;action_controller&#x2F;routing&#x2F;recognition_optimisation.rb&quot;&gt;code comments&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changesets: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8674&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8674&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8652&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8652&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;render :partial and forms&lt;&#x2F;h3&gt;
&lt;p&gt;Instead of doing:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_for(:person) do |f| %&amp;gt;
  &amp;lt;%= render :partial =&amp;gt; &#x27;form&#x27;, :locals =&amp;gt; { :form =&amp;gt; f } %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;you can now do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_for(:person) do |f| %&amp;gt;
  &amp;lt;%= render :partial =&amp;gt; f %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Convenient. This also works with your &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActionView&#x2F;Helpers&#x2F;FormHelper.html#M000920&quot;&gt;custom form builders&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_for(:person, :builder =&amp;gt; LabellingFormBuilder) do |f| %&amp;gt;
  &amp;lt;%= render :partial =&amp;gt; f %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The partial template rendered is then &lt;code&gt;people&#x2F;_labelling_form&lt;&#x2F;code&gt; and the local variable in the partial is &lt;code&gt;labelling_form&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8646&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8646&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Callbacks refactored into ActiveSupport::Callbacks&lt;&#x2F;h3&gt;
&lt;p&gt;All that duplicated callback code in ActiveRecord, ActionController::Dispatcher, and in test case setup and teardown methods have been extracted into the ActiveSupport::Callbacks module.&lt;&#x2F;p&gt;
&lt;p&gt;Less duplication means more robust code so yay!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8664&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8664&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveRecord test suite gets a makeover&lt;&#x2F;h3&gt;
&lt;p&gt;The ActiveRecord test suite has become something of a maze jungle in recent times, with no clear hierarchy of how things are organize. It&#x27;s not that easy to find what you are looking for especially for newcomers trying to contribute to ActiveRecord. Thankfully, someone (John Barnette - the foxy fixtures guy) has stepped up and cleaned things up quite a bit. Fixtures, test cases, fixture models, etc. are now in their own directories and from looking at the directory hierarchy one should be able to know where to put what at a glance.&lt;&#x2F;p&gt;
&lt;p&gt;Related ticket: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10742&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10742&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Bugfixes&lt;&#x2F;h3&gt;
&lt;p&gt;* &lt;code&gt;redirect_to nil&lt;&#x2F;code&gt; no longer explodes (but raises a friendlier &#x27;cannot redirect to nil&#x27; exception) (related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8633&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8633&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) #3 - X-Sendfile and many other sexy enhancements</title>
    <published>2008-01-16T23:25:48+00:00</published>
    <updated>2008-01-16T23:25:48+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/16/living-on-the-edge-of-rails-3-x-sendfile-and-many-other-sexy-enhancements/"/>
    <id>https://chuyeow.wtf/2008/01/16/living-on-the-edge-of-rails-3-x-sendfile-and-many-other-sexy-enhancements/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/16/living-on-the-edge-of-rails-3-x-sendfile-and-many-other-sexy-enhancements/">&lt;p&gt;Edge Rails saw a barrage of refinements and enhancements this week and there&#x27;s even talk about Rails 2.1 being just a little around the corner. There&#x27;s also been a flurry of contributions to making Rails more thread-safe and performance optimizations (all still work in progress at the moment) - it&#x27;s really nice to see how the Rails community is looking seriously at performance post-Rails 2.0 (not that they weren&#x27;t serious about performance before Rails 2.0!).&lt;&#x2F;p&gt;
&lt;p&gt;This week’s report covers changes from 7 Jan 2008 to the day the corresponding &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;2008&#x2F;1&#x2F;16&#x2F;rails-envy-podcast-episode-014-1-16-2008&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt; was recorded (13 Jan 2008).&lt;&#x2F;p&gt;
&lt;h3&gt;X-Sendfile gets easier with send_file :x_sendfile =&gt; true&lt;&#x2F;h3&gt;
&lt;p&gt;If you only have a vague idea of what it is (like, X-Sendfile is that thing that lets you send files, right?), you&#x27;d do well to read this &lt;a href=&quot;http:&#x2F;&#x2F;john.guen.in&#x2F;past&#x2F;2007&#x2F;4&#x2F;17&#x2F;send_files_faster_with_xsendfile&#x2F;&quot;&gt;helpful explanation&lt;&#x2F;a&gt;. (In short, X-Sendfile allows you to send static files directly and more performantly to HTTP clients and bypassing your app server process.) You don&#x27;t have to set those headers yourself or install the plugin mentioned in that article though, since edge Rails has an augmented &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActionController&#x2F;Streaming.html#M000228&quot;&gt;&lt;code&gt;send_file&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; helper that does all the legwork for you.&lt;&#x2F;p&gt;
&lt;p&gt;All you have to do now is to this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;send_file &#x27;&#x2F;path&#x2F;to.png&#x27;, :x_sendfile =&amp;gt; true, :type =&amp;gt; &#x27;image&#x2F;png&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Rails will set the X-Sendfile header for you (i.e. &lt;code&gt;response.headers[&#x27;X-Sendfile&#x27;] = &#x27;&#x2F;path&#x2F;to.png&#x27;&lt;&#x2F;code&gt;) and sends a HEAD response (empty response body) with the file path, allowing your web server (Apache, Lighttpd) to serve the static file and not involve your Rails processes (such as your precious, perpertually resource-starved &lt;a href=&quot;http:&#x2F;&#x2F;mongrel.rubyforge.org&#x2F;&quot;&gt;mongrels&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;This is &lt;em&gt;really&lt;&#x2F;em&gt; nice if you are serving lots of static files (downloadable images and documents come to mind) and are not already using X-Sendfile or doing it the &quot;long&quot; way (by setting the response header and then &lt;code&gt;render :nothing =&gt; true&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8628&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8628&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActionController::Base.asset_host proc now takes the request object as an optional 2nd argument&lt;&#x2F;h3&gt;
&lt;p&gt;Rails 2.0.2 allowed you to set &lt;code&gt;ActionController::Base.asset_host&lt;&#x2F;code&gt; to a proc that took a single &lt;code&gt;source&lt;&#x2F;code&gt; argument (as &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;17&#x2F;rails-202-released-so-whats-new&#x2F;&quot;&gt;detailed in my earlier post&lt;&#x2F;a&gt;). People were still &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10549&quot;&gt;running into problems&lt;&#x2F;a&gt; with asset hosting though, particularly while trying to serve assets from an SSL-protected page (i.e. HTTPS requests). When serving SSL-protected pages, you&#x27;d need to either have an SSL certificate for each asset host(!) or live with a mixed media warning (which browsers report when you have SSL and non-SSL content on the same page).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;asset_host&lt;&#x2F;code&gt; proc now takes the entire controller request instance as an optional second argument. This allows you to either use a single asset host or to disable asset hosting for SSL requests. For example, this proc below practically disables asset hosting:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActionController::Base.asset_host = Proc.new { |source, request| 
  if request.ssl? 
    &quot;#{request.protocol}#{request.host_with_port}&quot; # Disable asset hosting.
  else 
    &quot;#{request.protocol}assets.example.com&quot; # Use asset host.
  end 
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8578&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8578&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Nicer way to access request headers&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s now a nicer way to access headers - instead of &lt;code&gt;request.env[&quot;HTTP_CONTENT_TYPE&quot;]&lt;&#x2F;code&gt; you can now do &lt;code&gt;request.headers[&quot;Content-Type&quot;]&lt;&#x2F;code&gt; (or &lt;code&gt;request.headers[&quot;content-type&quot;]&lt;&#x2F;code&gt; (note all lowercase) or even good old &lt;code&gt;request.headers[&quot;HTTP_CONTENT_TYPE&quot;]&lt;&#x2F;code&gt;. How convenient - I often worry about getting the casing right (was it &#x27;Content-Type&#x27; or &#x27;Content-type&#x27;?) and now I can be sure it doesn&#x27;t matter!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8625&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8625&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;ActiveSupport::TestCase and friends now support declarative setup and teardown callbacks&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;ActiveSupport::TestCase&lt;&#x2F;code&gt; (and the &lt;code&gt;ActionController::TestCase&lt;&#x2F;code&gt; and &lt;code&gt;ActionMailer::TestCase&lt;&#x2F;code&gt; subclasses) now support declarative setup and teardown callbacks that are called before setup&#x2F;after teardown. For example,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class FooTestCase &amp;lt; ActiveSupport::TestCase
  setup :run_this_first, :then_run_this do
    # Run this last.
  end
  teardown :remove_tmp_files, :undef_constants
&lt;p&gt;def run_this_first
end&lt;&#x2F;p&gt;
&lt;p&gt;def then_run_this
end&lt;&#x2F;p&gt;
&lt;p&gt;def remove_tmp_files
end&lt;&#x2F;p&gt;
&lt;p&gt;def undef_constants
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;will run &lt;code&gt;run_this_first&lt;&#x2F;code&gt;, &lt;code&gt;then_run_this&lt;&#x2F;code&gt;, and finally the stuff that&#x27;s in the given block to &#x27;setup&#x27; before running the actual &lt;code&gt;setup&lt;&#x2F;code&gt; method. The teardown callbacks are done in reverse order, meaning &lt;code&gt;undef_constants&lt;&#x2F;code&gt; is called, and then &lt;code&gt;remove_tmp_files&lt;&#x2F;code&gt; (and then the actual &lt;code&gt;teardown&lt;&#x2F;code&gt; method).&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8570&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8570&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;TMail updated to 1.2.1&lt;&#x2F;h3&gt;
&lt;p&gt;The bundled &lt;a href=&quot;http:&#x2F;&#x2F;tmail.rubyforge.org&#x2F;&quot;&gt;TMail&lt;&#x2F;a&gt; library (that ActionMailer uses) has been updated from 1.1.0 to 1.2.1. This new version currently maintained by &lt;a href=&quot;http:&#x2F;&#x2F;lindsaar.net&#x2F;&quot;&gt;Mikel Lindsaar&lt;&#x2F;a&gt; promises bugfixes and greater test coverage. For more details, see &lt;a href=&quot;https:&#x2F;&#x2F;rubyforge.org&#x2F;frs&#x2F;shownotes.php?group_id=4512&amp;release_id=18049&quot;&gt;https:&#x2F;&#x2F;rubyforge.org&#x2F;frs&#x2F;shownotes.php?group_id=4512&amp;release_id=18049&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Mikel has been working with Rails core to get Tmail Ruby 1.9-compatible. Good work Mikel!&lt;&#x2F;p&gt;
&lt;p&gt;Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8620&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8620&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3&gt;Bug fixes&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;code&gt;ActionController::UrlWriter&lt;&#x2F;code&gt; respects the &lt;code&gt;relative_url_root&lt;&#x2F;code&gt;. For those of you who don&#x27;t know, the &lt;code&gt;ActionController::UrlWriter&lt;&#x2F;code&gt; module is a convenient mixin that allows you to use &lt;code&gt;url_for&lt;&#x2F;code&gt; &lt;em&gt;and&lt;&#x2F;em&gt; your named routes in arbitrary classes (such as in your mailers or in a BackgrounDRb worker).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class SitemapWorker &amp;lt; BackgrounDRb::MetaWorker
  &lt;strong&gt;include ActionController::UrlWriter&lt;&#x2F;strong&gt;
&lt;h1 id=&quot;access-your-named-routes-and-the-url-for-helper&quot;&gt;Access your named routes and the url_for helper.&lt;&#x2F;h1&gt;
&lt;p&gt;url = page_url(:permalink =&amp;gt; &#x27;foo&#x27;)
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;  And now it respects your &lt;code&gt;relative_url_root&lt;&#x2F;code&gt; instead of blissfully ignoring it.&lt;&#x2F;p&gt;
&lt;p&gt;  Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8616&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8616&lt;&#x2F;a&gt;
  &lt;&#x2F;li&gt;
&lt;li&gt;
    &lt;code&gt;render :text =&gt; nil&lt;&#x2F;code&gt; and &lt;code&gt;render :text =&gt; false&lt;&#x2F;code&gt; work properly now instead of inexplicably trying to render a file. This was a big gotcha when using &lt;code&gt;render :text =&gt; some_variable&lt;&#x2F;code&gt; where &lt;code&gt;some_variable&lt;&#x2F;code&gt; could potentially be false or nil in some cases - Obie Fernandez has a &lt;a href=&quot;http:&#x2F;&#x2F;www.jroller.com&#x2F;obie&#x2F;entry&#x2F;render_text_gotcha&quot;&gt;writeup on this long-standing bug&lt;&#x2F;a&gt;. Related changeset: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8577&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8577&lt;&#x2F;a&gt;
  &lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;Optimizations&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;re significant performance improvements for classic fixtures with HABTM data, due to some slightly clever caching model classes, and instantiating fixtures from the model class, instead of expensive constant lookups from the name of the class.&lt;&#x2F;p&gt;
&lt;p&gt;Related changesets: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8560&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8560&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8561&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8561&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Retrying code blocks in Ruby (on exceptions, whatever)</title>
    <published>2008-01-14T18:13:47+00:00</published>
    <updated>2008-01-14T18:13:47+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/"/>
    <id>https://chuyeow.wtf/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/">&lt;p&gt;I am not certain whether the ability to retry a code block when encountering exceptions was a feature available in Ruby, but I certainly couldn&#x27;t find anything on that topic (what I did find were mostly about the &lt;code&gt;retry&lt;&#x2F;code&gt; keyword for iterator loops).&lt;&#x2F;p&gt;
&lt;p&gt;Before you ask why I need this, the motivation for this was because I was getting intermittent HTTP errors (503s mostly) trying to connect to a web service. Turns out it&#x27;s really easy in Ruby to implement a &lt;code&gt;retryable&lt;&#x2F;code&gt; method that does something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;retryable(:tries =&gt; 5, :on =&gt; OpenURI::HTTPError) do
  open(&#x27;http:&#x2F;&#x2F;example.com&#x2F;flaky_api&#x27;)
  # Code that mashes up stuff for your &quot;social networking&quot; site.
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here are the &lt;a href=&quot;http:&#x2F;&#x2F;pastie.caboo.se&#x2F;138570&quot;&gt;Kernel#retryable specs (pastie)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;And the code:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# Options:
# * :tries - Number of retries to perform. Defaults to 1.
# * :on - The Exception on which a retry will be performed. Defaults to Exception, which retries on any Exception.
#
# Example
# =======
#   retryable(:tries =&amp;gt; 1, :on =&amp;gt; OpenURI::HTTPError) do
#     # your code here
#   end
#
def retryable(options = {}, &amp;block)
  opts = { :tries =&gt; 1, :on =&gt; Exception }.merge(options)
&lt;p&gt;retry_exception, retries = opts[:on], opts[:tries]&lt;&#x2F;p&gt;
&lt;p&gt;begin
return yield
rescue retry_exception
retry if (retries -= 1) &amp;gt; 0
end&lt;&#x2F;p&gt;
&lt;p&gt;yield
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s not hard to implement the same for checking return values as well, i.e.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;retryable_deluxe(:tries =&amp;gt; 5, :on =&amp;gt; { :return =&amp;gt; nil }) { puts &quot;working...&quot; }
&lt;p&gt;retryable_deluxe(:on =&amp;gt; { :exception =&amp;gt; StandardError, :return =&amp;gt; nil }) do&lt;&#x2F;p&gt;
&lt;h1 id=&quot;your-code-here&quot;&gt;your code here&lt;&#x2F;h1&gt;
&lt;p&gt;end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ruby is nice.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) - 1st week of the year edition</title>
    <published>2008-01-09T22:18:20+00:00</published>
    <updated>2008-01-09T22:18:20+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/09/living-on-the-edge-of-rails-1st-week-of-the-year-edition/"/>
    <id>https://chuyeow.wtf/2008/01/09/living-on-the-edge-of-rails-1st-week-of-the-year-edition/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/09/living-on-the-edge-of-rails-1st-week-of-the-year-edition/">&lt;p&gt;Yup, it&#x27;s time for your weekly dose of the changes on edge Rails, more or less covered in the latest &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;2008&#x2F;1&#x2F;9&#x2F;rails-envy-podcast-episode-013-1-9-2008&quot;&gt;Rails Envy podcast&lt;&#x2F;a&gt;. Using edge Rails is neither arcane nor terrifying, and hopefully weekly reports like these will allow you to &lt;a href=&quot;http:&#x2F;&#x2F;www.loudthinking.com&#x2F;posts&#x2F;20-dont-overestimate-the-power-of-versions&quot;&gt;take control of your own release schedule&lt;&#x2F;a&gt; with your Rails apps.&lt;&#x2F;p&gt;
&lt;p&gt;This week&#x27;s report covers changes from 31 Dec 2007 to the day the podcast was recorded (6 Jan 2007).&lt;&#x2F;p&gt;
&lt;h3&gt;Caching changes&lt;&#x2F;h3&gt;
&lt;p&gt;Looks like most of the changes from the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;branches&#x2F;2-1-caching&quot;&gt;2.1 caching branch&lt;&#x2F;a&gt; have been&lt;br &#x2F;&gt;
&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8546&quot;&gt;merged into the trunk&lt;&#x2F;a&gt;. Some key points:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;memcache-client has been &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;vendor&#x2F;memcache-client-1.5.0&quot;&gt;vendored&lt;&#x2F;a&gt; (included in Rails directly). MemCacheStore works out of the box in Rails now, no need to install the &lt;a href=&quot;http:&#x2F;&#x2F;dev.robotcoop.com&#x2F;Libraries&#x2F;memcache-client&#x2F;&quot;&gt;memcache-client gem&lt;&#x2F;a&gt;!&lt;&#x2F;li&gt;
&lt;li&gt;The caching code has been refactored and moved into ActiveSupport (&lt;code&gt;ActiveSupport::Cache::*&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Added &lt;code&gt;ActiveRecord::Base.cache_key&lt;&#x2F;code&gt; to make it easier to cache Active Records in combination with the ActiveSupport cache libraries introduced in this changeset.&lt;&#x2F;li&gt;
&lt;li&gt;Fragment cache keys are now by default prefixed with &#x27;views&#x2F;&#x27;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Deprecation&lt;&#x2F;em&gt;: &lt;code&gt;ActionController::Base.fragment_cache_store&lt;&#x2F;code&gt; is now &lt;code&gt;ActionController::Base.cache_store&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3&gt;Fragment caching now works in RJS and Builder templates&lt;&#x2F;h3&gt;
&lt;p&gt;Yup, you couldn&#x27;t do fragment caching in non-erb views before - &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8542&quot;&gt;now you can&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Freezing Rails now automatically updates your Rails app&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;re using edge Rails and use the &lt;code&gt;rails:freeze:edge&lt;&#x2F;code&gt; rake task, you probably usually forget to run (or maybe you&#x27;re not even aware of) &lt;code&gt;rake rails:update&lt;&#x2F;code&gt; to update your Rails app with the latest config&#x2F;, scripts&#x2F; and javascript files from the version of Rails you just froze to. On edge Rails, the &lt;code&gt;rake rails:freeze:edge&lt;&#x2F;code&gt; task runs the &lt;code&gt;rails:update&lt;&#x2F;code&gt; task for you. +1 for convenience!&lt;&#x2F;p&gt;
&lt;p&gt;I prefer to use &lt;a href=&quot;http:&#x2F;&#x2F;piston.rubyforge.org&#x2F;&quot;&gt;Piston&lt;&#x2F;a&gt; so I&#x27;m gonna have to keep remembering to run my &lt;code&gt;rake rails:update&lt;&#x2F;code&gt; now and then!&lt;&#x2F;p&gt;
&lt;p&gt;Check out the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8532&quot;&gt;related changeset&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Optimizations&lt;&#x2F;h3&gt;
&lt;p&gt;Only 1 optimization in the past week worth talking about: the &lt;code&gt;ActiveRecord::Base#exists?&lt;&#x2F;code&gt; method is faster. It now uses &lt;code&gt;ActiveRecord::Base#select_all&lt;&#x2F;code&gt; instead of a more expensive &lt;code&gt;ActiveRecord::Base#find&lt;&#x2F;code&gt; that unnecessarily instantiates AR objects. (Check out the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8531&quot;&gt;related changeset&lt;&#x2F;a&gt;.)&lt;&#x2F;p&gt;
&lt;h3&gt;Bug fixes&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8541&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8541&lt;&#x2F;a&gt; - Fixed a nasty bug when trying to render partials with layout when done from within the site layout. Yes, you can have &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2007&#x2F;8&#x2F;3&#x2F;what-s-new-in-edge-rails-partials-get-layouts&quot;&gt;layouts for your partials in Rails 2&lt;&#x2F;a&gt;, and yes, you can run into a bug when trying to use partial layouts in your main page layout.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8529&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8529&lt;&#x2F;a&gt; - Fix &lt;code&gt;atom_feed_helper&lt;&#x2F;code&gt; to comply with the &lt;a href=&quot;http:&#x2F;&#x2F;atomenabled.org&#x2F;developers&#x2F;syndication&#x2F;atom-format-spec.php&quot;&gt;Atom specifications&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>self.plug :with =&gt; &#x27;Rails Hackfest&#x27;</title>
    <published>2008-01-03T23:24:27+00:00</published>
    <updated>2008-01-03T23:24:27+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/03/selfplug-with-rails-hackfest/"/>
    <id>https://chuyeow.wtf/2008/01/03/selfplug-with-rails-hackfest/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/03/selfplug-with-rails-hackfest/">&lt;p&gt;Yes, it&#x27;s a &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2008&#x2F;1&#x2F;3&#x2F;december-hackfest-winners-announced&quot;&gt;plug for myself&lt;&#x2F;a&gt; and it&#x27;s shameless:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;rails-hackfest-dec-2007_thumb.jpg&quot; alt=&quot;Dec 2007 Rails Hackfest&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whatever &lt;a href=&quot;http:&#x2F;&#x2F;www.zedshaw.com&#x2F;rants&#x2F;rails_is_a_ghetto.html&quot;&gt;Zed Shaw may say about Rails its community&lt;&#x2F;a&gt;, Rails has done a huge part in making web development fun again for jaded web developers (first-time web developers probably won&#x27;t be able to tell the difference), and more importantly, raising the profile of Ruby more than any other Ruby project&#x2F;library&#x2F;framework&#x2F;tool ever did (and I&#x27;m sure we&#x27;re all constantly rolling our eyeballs at the new web frameworks that&#x27;re so terribly familiarly Rails-like). Hell, I bet at least 90% of Rubyists now wouldn&#x27;t even be Rubyists if they hadn&#x27;t come across the &lt;a href=&quot;http:&#x2F;&#x2F;rubyonrails.org&#x2F;&quot;&gt;web framework that could&lt;&#x2F;a&gt; 2 or 3 years ago. So yes I&#x27;d still be contributing to Rails so that it can make my life as a web developer easier, thank you.&lt;&#x2F;p&gt;
&lt;p&gt;I think I had about 18 accepted patches in &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;hackfest&#x2F;18-monthly-december-2-7&quot;&gt;December 2007 Rails Hackfest&lt;&#x2F;a&gt; (a few of the patches were not attributed properly in the Hackfest due to technical issues with the Rails Hackfest site).&lt;&#x2F;p&gt;
&lt;p&gt;Probably the only significant patches were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Allowing a proc to be set for &lt;code&gt;ActionController::Base.asset_host&lt;&#x2F;code&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8421&quot;&gt;changeset 8421&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;to_xml&lt;&#x2F;code&gt; should not automatically pass &lt;code&gt;:procs&lt;&#x2F;code&gt; to associations included with &lt;code&gt;:include&lt;&#x2F;code&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8258&quot;&gt;changeset 8258&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course Ruby 1.9 compatibility was a big deal in December 2007 since that Ruby 1.9 was targetted to be released on Christmas (changesets &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8369&quot;&gt;8369&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8399&quot;&gt;8309&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8398&quot;&gt;8398&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8397&quot;&gt;8397&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8412&quot;&gt;8412&lt;&#x2F;a&gt;). Yes, I know, Ruby 1.9 is a development release.&lt;&#x2F;p&gt;
&lt;p&gt;There were also broken tests to be fixed (changeset &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8271&quot;&gt;8271&lt;&#x2F;a&gt;), bugs to be fixed (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8340&quot;&gt;fixing &lt;code&gt;Array#to_sentence&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;), and some refactoring (changesets &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8343&quot;&gt;8343&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8522&quot;&gt;8522&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;And what would patching Rails be without random documentation fixes (changesets &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8457&quot;&gt;8457&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8471&quot;&gt;8471&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8472&quot;&gt;8472&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8280&quot;&gt;8280&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8279&quot;&gt;8279&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8278&quot;&gt;8278&lt;&#x2F;a&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8521&quot;&gt;8521&lt;&#x2F;a&gt;). The API documentation always needs a hand, so if you see any outdated or incorrect documentation, or think you can improve them with better examples or whatever, just &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;&quot;&gt;submit a patch&lt;&#x2F;a&gt; (it&#x27;s easy and should take you all of 3 minutes).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;hackfest&#x2F;21-monthly-january-2-8&quot;&gt;This month&#x27;s hackfest&lt;&#x2F;a&gt; has a terribly attractive &lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;hackfest&#x2F;21-monthly-january-2-8&#x2F;prizes&quot;&gt;top prize of a RailsConf ticket&lt;&#x2F;a&gt;. Too bad I won&#x27;t be able to take part in this month&#x27;s hackfest since winners of past month&#x27;s hackfest are automatically excluded from the next&#x27;s. But maybe you can ;).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Living on the Edge (of Rails) - the pilot</title>
    <published>2008-01-02T19:30:57+00:00</published>
    <updated>2008-01-02T19:30:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/02/whats-new-on-edge-rails-the-pilot/"/>
    <id>https://chuyeow.wtf/2008/01/02/whats-new-on-edge-rails-the-pilot/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/02/whats-new-on-edge-rails-the-pilot/">&lt;p&gt;Gregg Pollack of &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;&quot;&gt;Rails Envy&lt;&#x2F;a&gt; (the guys behind your favorite &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;tags&#x2F;Commercials&quot;&gt;Ruby on Rails vs everything commercials&lt;&#x2F;a&gt;) asked me recently whether I could provide them with weekly updates of changes on edge Rails for the &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;podcast&quot;&gt;Rails Envy Podcast&lt;&#x2F;a&gt; (which is often hilarious besides being informative), seeing as I am already keeping up with developments on the Rails trunk while doing my small part contributing to Rails. Of course, I responded with a +1.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;2008&#x2F;1&#x2F;2&#x2F;rails-envy-podcast-episode-012-1-2-2008&quot;&gt;The podcast is now available&lt;&#x2F;a&gt; and contains only abbreviated notes about the changes that I&#x27;d sent over to Gregg, so here&#x27;s the detailed version of changes on edge Rails from the release of Rails 2.0.2 (17 Dec 2007) to the day the podcast was recorded (30 Dec 2007).&lt;&#x2F;p&gt;
&lt;h3&gt;Noteworthy changes on edge Rails: 2007-12-17 to 2007-12-30&lt;&#x2F;h3&gt;
&lt;h4&gt;Native mongrel handler&lt;&#x2F;h4&gt;
&lt;p&gt;A native Mongrel handler has been &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8488&quot;&gt;introduced&lt;&#x2F;a&gt;. This is so that it can be worked on independent of &lt;a href=&quot;http:&#x2F;&#x2F;mongrel.rubyforge.org&#x2F;&quot;&gt;Mongrel&lt;&#x2F;a&gt;&#x27;s release cycle (the Rails handler is currently in the Mongrel codebase). &lt;a href=&quot;bitsweat.net&#x2F;&quot;&gt;Jeremy Kemper&lt;&#x2F;a&gt; (bitsweat) has already made a minor performance improvement by moving the mutex from the handler itself into the dispatcher. This means that as Rails gets more threadsafe, the Rails team can push the mutex further down so that it&#x27;s not a (scary) giant lock (the existing Mongrel Rails handler has a synchronized block around Rails&#x27; dispatcher).&lt;&#x2F;p&gt;
&lt;p&gt;Note: The native mongrel handler is not used by default at this time on edge Rails.&lt;&#x2F;p&gt;
&lt;h4&gt;Caching branch for Rails 2.1&lt;&#x2F;h4&gt;
&lt;p&gt;A &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;log&#x2F;branches&#x2F;2-1-caching&quot;&gt;caching branch&lt;&#x2F;a&gt; has been introduced, targeted for Rails 2.1. Other than being a big refactoring, there&#x27;s also native cache key management (e.g. &lt;code&gt;Product.find(5).cache_key # =&gt; &quot;products&#x2F;5&quot;&lt;&#x2F;code&gt;) and memcache integration is also being looked at.&lt;&#x2F;p&gt;
&lt;h4&gt;Ruby 1.9 compatibility continues...&lt;&#x2F;h4&gt;
&lt;p&gt;Yup, work on Ruby 1.9 compatibility for Rails continues. Rails is fortunate to have committers and contributors who are so keen on being 1.9-compatible - free performance gains are hard to turn down after all. There&#x27;s been lots of patching going on to deal with the changes in Ruby 1.9 (Unicode changes, new syntax, deprecations, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;Yes, the Rails committers and contributors working on 1.9-compatibility are fully aware that Ruby 1.9 is a &lt;strong&gt;development&lt;&#x2F;strong&gt; release, but nothing&#x27;s lost in making sure Rails is compatible with a version of Ruby that will eventually be a production version of Ruby. Besides, I think most of the 1.9-compatibility contributors have a dream that sometime soon, when Ruby 1.9 becomes &quot;stable&quot; enough, we&#x27;d be running our Rails applications on Ruby 1.9 for a free performance boost.&lt;&#x2F;p&gt;
&lt;p&gt;Too bad running Rails on Ruby 1.9 is not really possible at the moment since other projects like Mongrel need to be updated for Ruby 1.9 as well, first.&lt;&#x2F;p&gt;
&lt;h4&gt;Bugfixes&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;27&#x2F;dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7&#x2F;&quot;&gt;new TestCase subclasses&lt;&#x2F;a&gt; (&lt;code&gt;ActionController::TestCase&lt;&#x2F;code&gt;,&lt;br &#x2F;&gt;
  &lt;code&gt;ActionMailer::TestCase&lt;&#x2F;code&gt;) introduced in Rails 2 have a &lt;a href=&quot;http:&#x2F;&#x2F;quotedprintable.com&#x2F;2007&#x2F;12&#x2F;5&#x2F;potential-gotcha-with-test-setup-in-rails-2-0&quot;&gt;gotcha&lt;&#x2F;a&gt;. This has been &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8497&quot;&gt;fixed&lt;&#x2F;a&gt; quickly by &lt;a href=&quot;http:&#x2F;&#x2F;joshpeek.com&#x2F;&quot;&gt;Josh Peek&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Fixed a bug where trying to :include for a belongs_to association inferred the foreign key incorrectly from the class name, rather than from the association name (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8456&quot;&gt;changeset&lt;&#x2F;a&gt; contributed by &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;4985-jonathan-viney&quot;&gt;Jonathan Viney&lt;&#x2F;a&gt;). Code is probably easier to understand:
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Post &amp;lt; ActiveRecord::Base
  belongs_to :main_category, :class_name =&amp;gt; &#x27;Category&#x27;
end
&lt;p&gt;Post.find(:first, :include =&amp;gt; :main_category)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;activerecord-statementinvalid-mysql-error-unknown-column&quot;&gt;=&amp;gt; ActiveRecord::StatementInvalid: Mysql::Error: Unknown column&lt;&#x2F;h1&gt;
&lt;p&gt;&#x27;posts.category&#x27; in &#x27;on clause&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4&gt;Optimizations&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8505&quot;&gt;JSON decoding is faster&lt;&#x2F;a&gt;. This helps if you&#x27;re doing a lot of JSON decoding or deserialization (such as via &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActiveRecord&#x2F;Serialization.html#M001136&quot;&gt;&lt;code&gt;ActiveRecord::Base#from_json&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;), or you are using the &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActiveResource&#x2F;Base.html#M000827&quot;&gt;JSON format for ActiveResource&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;has_many&lt;&#x2F;code&gt; associations are &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8504&quot;&gt;no longer loaded unnecessarily&lt;&#x2F;a&gt; in &lt;code&gt;after_update&lt;&#x2F;code&gt; callbacks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;I can has feedback nao plz?&lt;&#x2F;h3&gt;
&lt;p&gt;Please leave any suggestions for improvements you may have - about anything really: format, level of detail, what you&#x27;d like to see, whatever. Until next week...&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Why I love RSpec nested example groups</title>
    <published>2007-12-30T13:16:49+00:00</published>
    <updated>2007-12-30T13:16:49+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/30/why-i-love-rspec-nested-example-groups/"/>
    <id>https://chuyeow.wtf/2007/12/30/why-i-love-rspec-nested-example-groups/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/30/why-i-love-rspec-nested-example-groups/">&lt;p&gt;Prior to the introduction of &lt;a href=&quot;http:&#x2F;&#x2F;blog.davidchelimsky.net&#x2F;articles&#x2F;2007&#x2F;11&#x2F;29&#x2F;nested-example-groups&quot;&gt;nested example groups&lt;&#x2F;a&gt; in &lt;a href=&quot;http:&#x2F;&#x2F;rspec.info&#x2F;&quot;&gt;RSpec&lt;&#x2F;a&gt;, I&#x27;d always felt that descriptions got a little unwieldy when trying to describe the different cases and disliked specifying the &lt;code&gt;controller_name&lt;&#x2F;code&gt; repeatedly. For example (and these are real examples from real projects at work, with actual code removed for conciseness):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe &#x27;POST HotelDealsController#create with a valid hotel deal&#x27; do
  controller_name :hotel_deals
&lt;p&gt;before(:each) do
# ...
end&lt;&#x2F;p&gt;
&lt;p&gt;it &quot;should create and save a new hotel deal&quot; do
# ...
end
end&lt;&#x2F;p&gt;
&lt;p&gt;describe &#x27;POST HotelDealsController#create with an invalid hotel deal&#x27; do
controller_name :hotel_deals&lt;&#x2F;p&gt;
&lt;p&gt;before(:each) do
# ...
end&lt;&#x2F;p&gt;
&lt;p&gt;it &quot;should not perform any redirection&quot; do
# ...
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nested example groups allow me to do this instead:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe SearchController do
  before(:each) do
    @search = mock_model(Search)
  end
&lt;p&gt;describe &quot;POST &#x27;create&#x27;&quot; do&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;it &amp;quot;should render &amp;#39;new&amp;#39; when creating an invalid search&amp;quot; do
  # ...
end

describe &amp;quot;with a valid search that has a location_id&amp;quot; do
  before(:each) do
    @search.stub!(:valid?).and_return(true)
    @search.stub!(:location_id).and_return(1)
  end

  it &amp;quot;should save a new search that has a location_id, location_code and location_name, and redirect to &amp;#39;show&amp;#39;&amp;quot; do
    # ...
  end
end

describe &amp;quot;with a valid search that doesn&amp;#39;t have a location_id&amp;quot; do
  before(:each) do
    @search.stub!(:valid?).and_return(true)
    @search.stub!(:location_id).and_return(nil)
  end

  it &amp;quot;should ask the Location model for possible locations if the search doesn&amp;#39;t have a location_id&amp;quot; do
    # ...
  end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;What&#x27;s the difference you say? Well, while it may sound trivial, I can do &lt;code&gt;describe SearchController&lt;&#x2F;code&gt; only once and nest all examples for the different actions and scenarios inside without breaking it up into separate top-level example groups where I&#x27;d need to say &lt;code&gt;controller_name :search&lt;&#x2F;code&gt; multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;Another (more important) benefit is I can &lt;em&gt;progessively specify different scenarios&lt;&#x2F;em&gt; I want to test by nesting them and providing a &lt;code&gt;before&lt;&#x2F;code&gt; block to setup mocks and stubs &lt;em&gt;for that specific scenario&lt;&#x2F;em&gt;. Let&#x27;s look at what I mean with some code. Over here, I&#x27;m specifying the &lt;code&gt;create&lt;&#x2F;code&gt; action of my &lt;code&gt;SearchController&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
describe &quot;POST &#x27;create&#x27;&quot; do
  it &quot;should render &#x27;new&#x27; when creating an invalid search&quot; do
    # ...
  end
&lt;p&gt;describe &quot;with a valid search that has a location_id&quot; do
# ...
end&lt;&#x2F;p&gt;
&lt;p&gt;describe &quot;with a valid search that doesn&#x27;t have a location_id&quot; do
# ...
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;re 3 possible scenarios here: an invalid search, a valid search with a location_id, and a valid search without an location_id. I can write examples for invalid searches within the top-level example group itself (&lt;code&gt;it &quot;should render &#x27;new&#x27; when creating an invalid search&quot;&lt;&#x2F;code&gt;). Now, to test valid searches, I break out 2 nested example groups with their own &lt;code&gt;before&lt;&#x2F;code&gt; block to setup mock searches, one which has a location_id, the other doesn&#x27;t. What&#x27;s the big deal? It just feels much more organized than the first, non-nested example where a top-level example group is created for each scenario.&lt;&#x2F;p&gt;
&lt;p&gt;And I know it may not seem like much, and I don&#x27;t think there&#x27;s anything particularly wrong with non-nested examples - it&#x27;s a matter of personal preference. Nesting allows me to write examples for controllers in a saner fashion where I can say confidently to myself that &quot;all examples for XXX action go here&quot;. I&#x27;m a big believer in readable tests (if you&#x27;re on the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;&quot;&gt;Rails Trac&lt;&#x2F;a&gt; much and have seen my reviews and patches you should know), so being able to write specs where I feel they belong makes me happier, and the examples read really nicely too.&lt;&#x2F;p&gt;
&lt;p&gt;I guess what I&#x27;m really trying to say is this: when trying to add a new example to legacy specs (legacy being anything that was written more than 5 mins ago) I &lt;strong&gt;instantly know where to place it&lt;&#x2F;strong&gt; - gone are the days of going through different example groups looking for the right place to put my new specification (and often settling on just simply creating a new top-level example group). I like to think we&#x27;ve all been there.&lt;&#x2F;p&gt;
&lt;p&gt;That said, I&#x27;m not saying that deeply nested examples are a good thing. When testing Rails controllers I find that you don&#x27;t often have to go more than 3 deep to allow for all the possible scenarios. Any more would suggest that your controller is doing too much work.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>DRY in your functional and ActionMailer tests - Rails 2.0 a feature a day #7</title>
    <published>2007-12-27T18:47:06+00:00</published>
    <updated>2007-12-27T18:47:06+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/27/dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7/"/>
    <id>https://chuyeow.wtf/2007/12/27/dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/27/dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7/">&lt;p&gt;That&#x27;s right, &lt;strong&gt;D&lt;&#x2F;strong&gt;on&#x27;t &lt;strong&gt;R&lt;&#x2F;strong&gt;epeat &lt;strong&gt;Y&lt;&#x2F;strong&gt;ourself in your functional and ActionMailer tests. If you&#x27;re a Test::Unit user, this will probably look familiar to you when writing Rails functional tests (for your controllers):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PostsControllerTest &amp;lt; Test::Unit::TestCase
  def setup
    @controller = PostsController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
  end
&lt;p&gt;def test_should_not_explode
# Invariably sexy test code.
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;d probably have noticed how &lt;code&gt;setup&lt;&#x2F;code&gt; &lt;em&gt;always&lt;&#x2F;em&gt; sets the &lt;code&gt;@controller&lt;&#x2F;code&gt;, &lt;code&gt;@request&lt;&#x2F;code&gt; and &lt;code&gt;@response&lt;&#x2F;code&gt; instance variables in all your controller tests. In Rails 2.0, you can instead subclass &lt;code&gt;ActionController::TestCase&lt;&#x2F;code&gt; (in turn a subclass of &lt;code&gt;Test::Unit::TestCase&lt;&#x2F;code&gt;) in your test cases and avoid repeating the instance variable assignments.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PostsControllerTest &amp;lt; ActionController::TestCase
  # No need to define setup.
&lt;p&gt;def test_should_not_explode
# Invariably sexy test code.
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Isn&#x27;t that much better?&lt;&#x2F;p&gt;
&lt;p&gt;Watch out for a gotcha though, when you actually do need to define a &lt;code&gt;setup&lt;&#x2F;code&gt; method (like when you need to setup several other things before your tests run), as &lt;a href=&quot;http:&#x2F;&#x2F;quotedprintable.com&#x2F;2007&#x2F;12&#x2F;5&#x2F;potential-gotcha-with-test-setup-in-rails-2-0&quot;&gt;Jeffrey Allan Hardy reports&lt;&#x2F;a&gt;. &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8497&quot;&gt;The issue has been resolved&lt;&#x2F;a&gt; on edge Rails. If you&#x27;re not using edge Rails, you should remember to always call &lt;code&gt;super&lt;&#x2F;code&gt; in your &lt;code&gt;setup&lt;&#x2F;code&gt; method should you define one:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PostsControllerTest &amp;lt; ActionController::TestCase
  def setup
    super
    @user = users(:konata)
  end
&lt;p&gt;def test_should_not_explode
# Invariably sexy test code.
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A similar subclass of &lt;code&gt;Test::Unit&lt;&#x2F;code&gt;, &lt;code&gt;ActionMailer::TestCase&lt;&#x2F;code&gt; is available for your ActionMailer unit tests as well. That means you can replace this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class UserMailerTest &amp;lt; Test::Unit::TestCase
  include ActionMailer::Quoting
&lt;p&gt;def setup
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;@expected = TMail::Mail.new
@expected.set_content_type &amp;quot;text&amp;quot;, &amp;quot;plain&amp;quot;, { &amp;quot;charset&amp;quot; =&amp;gt; &amp;quot;utf-8&amp;quot; }
@expected.mime_version = &amp;#39;1.0&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end&lt;&#x2F;p&gt;
&lt;p&gt;def test_signup
# Test code.
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class UserMailerTest &amp;lt; ActionMailer::TestCase
  def test_signup
    # Test code.
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the geeks among you, check out the related &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8022&quot;&gt;changeset&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, Michael Koziarski&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.koziarski.net&#x2F;&quot;&gt;Michael Koziarski&lt;&#x2F;a&gt;, better know as nzkoz, is a long-time &lt;a href=&quot;http:&#x2F;&#x2F;rubyonrails.com&#x2F;core&quot;&gt;Rails core&lt;&#x2F;a&gt; committer. Michael has done a signficant amount of work improving the performance of ActiveRecord for Rails 2.0 so we have him to thank for a good portion of the optimization work done on ActiveRecord. He also keeps a fairly new &lt;a href=&quot;http:&#x2F;&#x2F;www.koziarski.net&#x2F;&quot;&gt;personal blog&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Ruby 1.9.0 has been released</title>
    <published>2007-12-26T00:15:49+00:00</published>
    <updated>2007-12-26T00:15:49+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/26/ruby-190-has-been-released/"/>
    <id>https://chuyeow.wtf/2007/12/26/ruby-190-has-been-released/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/26/ruby-190-has-been-released/">&lt;p&gt;Just in the nick of time for the Christmas target, the Ruby core team has released Ruby 1.9.0 - &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Yukihiro_Matsumoto&quot;&gt;Matz&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;www.ruby-forum.com&#x2F;topic&#x2F;136553&quot;&gt;announced the release on the ruby-talk mailing list&lt;&#x2F;a&gt; not too long ago.&lt;&#x2F;p&gt;
&lt;p&gt;Rubygem and Ruby library developers, now&#x27;s the time to get down to making your Ruby code compatible with 1.9.0.&lt;&#x2F;p&gt;
&lt;p&gt;Rails is not too far from being compatible with 1.9, thanks to the efforts of &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;5323-jeremy-kemper&quot;&gt;Jeremy Kemper&lt;&#x2F;a&gt; and a few other contributors. Mongrel is not quite there yet though (I use mongrel for my Rails applications, and I think at least 50% of you do too). So while running your Rails apps on Ruby 1.9 is not an easy task right now (unless you enjoy lots of monkey patching), let&#x27;s hope the full 1.9.0 release will inspire more Ruby developers to get their libraries compatible so we can all enjoy the &lt;a href=&quot;http:&#x2F;&#x2F;antoniocangiano.com&#x2F;2007&#x2F;12&#x2F;03&#x2F;the-great-ruby-shootout&#x2F;&quot;&gt;big speed boost in Ruby 1.9&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Very nice (if somewhat geeky) Christmas present from the Ruby core and contributors!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>gchartrb = Ruby + Google Chart API</title>
    <published>2007-12-12T00:22:27+00:00</published>
    <updated>2007-12-12T00:22:27+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/12/gchartrb-ruby-google-chart-api/"/>
    <id>https://chuyeow.wtf/2007/12/12/gchartrb-ruby-google-chart-api/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/12/gchartrb-ruby-google-chart-api/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;apis&#x2F;chart&#x2F;&quot;&gt;Google Chart API&lt;&#x2F;a&gt; looks quite useful. I&#x27;ve used &lt;a href=&quot;http:&#x2F;&#x2F;nubyonrails.com&#x2F;pages&#x2F;gruff&quot;&gt;Gruff&lt;&#x2F;a&gt; to generate graphs before but this looks way easier (and much lighter on the server without all that ImageMagick magic!) I&#x27;ll have to play with it someday - if only I didn&#x27;t have to mess with those &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;apis&#x2F;chart&#x2F;#url_format&quot;&gt;URL params&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;Well, &lt;a href=&quot;http:&#x2F;&#x2F;blog.deepak.jois.name&#x2F;&quot;&gt;Deepak Jois&lt;&#x2F;a&gt; from &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;singapore-rb&#x2F;&quot;&gt;singapore.rb&lt;&#x2F;a&gt; (the local Ruby user group) recently &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;singapore-rb&#x2F;browse_thread&#x2F;thread&#x2F;47e81778350c37bb&quot;&gt;announced&lt;&#x2F;a&gt; a Ruby wrapper around the Google Chart API: &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;gchartrb&#x2F;&quot;&gt;gchartrb&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;gchartrb.rubyforge.org&#x2F;&quot;&gt;rdocs&lt;&#x2F;a&gt;). You can get it as a rubygem, just run:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;sudo gem install gchartrb&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looking good so far and I dig the familiarity - Deepak says the API is Gruff-inspired and it tells. If you need a charting solution (for reporting or whatever), this is a gem to consider.&lt;&#x2F;p&gt;
&lt;p&gt;Ah yup, there&#x27;ll be no &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;09&#x2F;rails-20-a-feature-a-day&#x2F;&quot;&gt;Rails 2 feature&lt;&#x2F;a&gt; today - just submitted a couple of Ruby 1.9 compatibility patches for Rails and feeling a little bummed out now (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;dependencies.rb&quot;&gt;dependency handling&lt;&#x2F;a&gt; is not that pleasant in Rails). &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;1689&quot;&gt;Rails&#x27; Ruby 1.9 compatibility&lt;&#x2F;a&gt; needs you!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Rails: a request profiler for profiling your app</title>
    <published>2007-10-26T10:01:30+00:00</published>
    <updated>2007-10-26T10:01:30+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/"/>
    <id>https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/10/26/new-in-rails-a-request-profiler-for-profiling-your-app/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;bitsweat.net&#x2F;&quot;&gt;Jeremy Kemper&lt;&#x2F;a&gt; (aka bitsweat) &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8016&quot;&gt;committed&lt;&#x2F;a&gt; a very useful tool into the Rails trunk not too long ago: a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;actionpack&#x2F;lib&#x2F;action_controller&#x2F;request_profiler.rb&quot;&gt;request profiler&lt;&#x2F;a&gt;! It&#x27;s a human-friendly wrapper script around the &lt;a href=&quot;http:&#x2F;&#x2F;ruby-prof.rubyforge.org&#x2F;&quot;&gt;ruby-prof library&lt;&#x2F;a&gt;, a nice ruby code profiler, that lets you run multiple requests against a URI in your application and get a detailed code profile report in text and HTML.&lt;&#x2F;p&gt;
&lt;p&gt;Wanna try it out? Update your vendor&#x2F;rails to at least revision 8016, run &lt;code&gt;rake rails:update&lt;&#x2F;code&gt; to copy the new &lt;code&gt;script&#x2F;performance&#x2F;request&lt;&#x2F;code&gt; script into your app&#x27;s &lt;code&gt;script&lt;&#x2F;code&gt; directory, install the ruby-prof gem (&lt;code&gt;sudo gem install ruby-prof&lt;&#x2F;code&gt;), then let it loose on your app.&lt;&#x2F;p&gt;
&lt;p&gt;The options are pretty simple, just pass the script the URI you wanna profile. There&#x27;re options for specifying how many requests you want to process, and for profiling POST requests, there&#x27;s one for&lt;br &#x2F;&gt;
specifying a POST fixture file.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;USAGE: script&#x2F;performance&#x2F;request uri [options]
    -u, --uri [URI]                  Request URI. Defaults to http:&#x2F;&#x2F;localhost:3000&#x2F;
    -n, --times [0000]               How many requests to process. Defaults to 1000.
    -b, --benchmark                  Benchmark instead of profiling
        --method [GET]               HTTP request method. Defaults to GET.
        --fixture [FILE]             Path to POST fixture file
        --open [CMD]                 Command to open profile results. Defaults to &quot;open %s &amp;&quot;
    -h, --help                       Show this help&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At the end of the run, you get a text and HTML report with the methods called and the time spent in them. If you haven&#x27;t seen a code profile before, it looks something like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;rails-request-prof-text-output_thumb.png&quot; alt=&quot;Rails request profiler text output report&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Very nice stuff! It&#x27;s &lt;em&gt;extremely&lt;&#x2F;em&gt; convenient to have profiling like this built into Rails itself - personally I&#x27;ve not even run any profiling on my Rails code because it seemed like a hassle (though I do run httperf benchmarks and take note the number of requests per second). With code profiling, you can easily see which parts of your code are the bottlenecks and optimize away - it&#x27;s a godsend that it&#x27;s so easy to do it in Rails!&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, this is all still new stuff I imagine and subject to change (and improvements), but still very exciting for those of us who are hitting performance bottlenecks in our Rails apps (and are not already doing code profiling).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>ActiveRecord attribute-related improvements on Edge Rails</title>
    <published>2007-08-14T17:54:16+00:00</published>
    <updated>2007-08-14T17:54:16+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/08/14/activerecord-attribute-related-improvements-on-edge-rails/"/>
    <id>https://chuyeow.wtf/2007/08/14/activerecord-attribute-related-improvements-on-edge-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/08/14/activerecord-attribute-related-improvements-on-edge-rails/">&lt;p&gt;I just noticed a very fresh changeset committed into the Rails trunk that&#x27;s pretty damn cool: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7315&quot;&gt;changeset 7315&lt;&#x2F;a&gt;. Michael Koziarski (aka nzkoz&quot;) has refactored ActiveRecord&#x27;s attribute-related methods that, among other things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;caches typecasted attribute values&lt;&#x2F;strong&gt; in hashes. This avoids expensive typecasting (such as for Time-related attributes) which means access to these fields is significantly faster!&lt;&#x2F;li&gt;
&lt;li&gt;moves generation of attribute methods to the &lt;strong&gt;class&lt;&#x2F;strong&gt;, instead of the instance.&lt;&#x2F;li&gt;
&lt;li&gt;generates attribute reader &lt;em&gt;and&lt;&#x2F;em&gt; writer methods (before, only reader methods were generated and writer methods relied on &lt;code&gt;method_missing&lt;&#x2F;code&gt; magic).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;rubyonrails-core&#x2F;browse_frm&#x2F;thread&#x2F;76b62bfb4448e4c3&quot;&gt;Ruby on Rails: Core Google Group thread on this patch&lt;&#x2F;a&gt; has more info on the changes and some of the rationale behind them.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a simple (read: totally unscientific) benchmark I ran to access a DateTime attribute 10000 times (I ran it that many times to reduce the effect of the &lt;code&gt;City.find&lt;&#x2F;code&gt; call) with pre-revision 7315 edge Rails (I was using revision 7314):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Benchmark.bmbm do |x| 
?&amp;gt;   x.report(&#x27;test&#x27;) { c = City.find(:first); 10000.times { c.created_at } }
&amp;gt;&amp;gt; end
Rehearsal ----------------------------------------
test   1.500000   0.010000   1.510000 (  1.568782)
------------------------------- total: 1.510000sec
&lt;pre&gt;&lt;code&gt;       user     system      total        real
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;test   1.500000   0.010000   1.510000 (  &lt;strong&gt;1.592264&lt;&#x2F;strong&gt;)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Post changeset 7315:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Benchmark.bmbm do |x| 
?&amp;gt;   x.report(&#x27;test&#x27;) { c = City.find(:first); 10000.times { c.created_at } }
&amp;gt;&amp;gt; end
Rehearsal ----------------------------------------
test   0.100000   0.010000   0.110000 (  0.129514)
------------------------------- total: 0.110000sec
&lt;pre&gt;&lt;code&gt;       user     system      total        real
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;test   0.000000   0.000000   0.000000 (  &lt;strong&gt;0.009831&lt;&#x2F;strong&gt;)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Quite a bit faster!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>God and your web server</title>
    <published>2007-07-18T23:43:38+00:00</published>
    <updated>2007-07-18T23:43:38+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/18/god-and-your-web-server/"/>
    <id>https://chuyeow.wtf/2007/07/18/god-and-your-web-server/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/18/god-and-your-web-server/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;god.rubyforge.org&#x2F;&quot;&gt;God&lt;&#x2F;a&gt; is a new process monitoring Ruby framework with a rather apt name (no, it&#x27;s not &lt;em&gt;that&lt;&#x2F;em&gt; &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;God&quot;&gt;God&lt;&#x2F;a&gt;). The config files looks something like that:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;God.meddle do |god|
  god.watch do |w|
    ...
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Interesting code to write. And feels safe too to have God watching over your mongrels. Oh and you can use it to clean up stale mongrel PID files without &lt;a href=&quot;http:&#x2F;&#x2F;textsnippets.com&#x2F;posts&#x2F;show&#x2F;931&quot;&gt;patching mongrel_rails&lt;&#x2F;a&gt;. Right now I use &lt;a href=&quot;http:&#x2F;&#x2F;www.tildeslash.com&#x2F;monit&#x2F;&quot;&gt;monit&lt;&#x2F;a&gt; a lot and it&#x27;s really rather unDRY to have repeated configs for each mongrel on the server (is there a better way of doing this in monit?). God would be able to DRY it up.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Better JSON output from Rails with the Jsonifier plugin</title>
    <published>2007-07-11T12:46:38+00:00</published>
    <updated>2007-07-11T12:46:38+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/"/>
    <id>https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/11/better-json-output-from-rails-with-the-jsonifier-plugin/">&lt;p&gt;&lt;ins&gt;Update: Edge Rails now does whatever Jsonifier does (and more). Check out my blog &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;10&#x2F;10&#x2F;new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity&#x2F;&quot;&gt;post on JSON serialization maturity in edge Rails&lt;&#x2F;a&gt;. This means that this plugin is virtually obsolete if you&#x27;re using edge Rails.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve tried to output JSON from your Rails applications before, you&#x27;d probably have noticed how inadequate it all seems. Let&#x27;s look at the kind of output (pretty-printed for easier reading) you get from calling &lt;code&gt;to_json&lt;&#x2F;code&gt; on your typical User model:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  attributes: {
    id: 1,
    name: &quot;Konata&quot;,
    awesome: true,
    created_at: &quot;07&#x2F;01&#x2F;2007&quot;
  }
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some of the common problems developers who write applications that speak JSON have with this are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;attributes&lt;&#x2F;code&gt; part is often unnecessary cruft when consuming ActiveRecord objects as JSON.&lt;&#x2F;li&gt;
&lt;li&gt;There&#x27;s no obvious way to control which attributes are shown in the JSON (e.g. you may want to hide private or lengthy attributes). The way to workaround this is either to write your own &lt;code&gt;to_json&lt;&#x2F;code&gt; instance method for your ActiveRecord model, or to use a Rails plugin (like &lt;a href=&quot;http:&#x2F;&#x2F;geekblog.vodpod.com&#x2F;?p=9&quot;&gt;acts_as_json&lt;&#x2F;a&gt;) or a &lt;a href=&quot;http:&#x2F;&#x2F;json.rubyforge.org&#x2F;&quot;&gt;gem&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Including 2nd (or higher order) associations is tricky (as above, you can achieve this by defining your own &lt;code&gt;to_json&lt;&#x2F;code&gt; instance methods).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3&gt;Under the hood of the current ActiveRecord#to_json&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;to_json&lt;&#x2F;code&gt; method for ActiveRecord objects falls back on using that defined in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&quot;&gt;ActiveSupport&#x27;s JSON classes&lt;&#x2F;a&gt;. The way it&#x27;s currently done, there are a bunch of JSON encoder classes defined for various types - when you call &lt;code&gt;to_json&lt;&#x2F;code&gt; on an ActiveRecord object it simply uses &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoders&#x2F;object.rb&quot;&gt;&lt;code&gt;Object#to_json&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;By the way, see that &lt;code&gt;created_at: &quot;07&#x2F;01&#x2F;2007&quot;&lt;&#x2F;code&gt; bit in the example above which is the JSON output for a Date attribute? That&#x27;s in MM&#x2F;DD&#x2F;YYYY format. Yup, 1st July 2007 not 7th January 2007 you &quot;rest of the world you&quot;. Ouch, but at least you can use JavaScript&#x27;s &lt;code&gt;Date.parse()&lt;&#x2F;code&gt; on it directly as detailed in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8399&quot;&gt;this patch&lt;&#x2F;a&gt;. And before you ask, yes, &lt;code&gt;Date.parse()&lt;&#x2F;code&gt; doesn&#x27;t understand the YYYY-MM-DD format.&lt;&#x2F;p&gt;
&lt;h3&gt;Can has Rails patch?&lt;&#x2F;h3&gt;
&lt;p&gt;So about 2 days ago, I wrote a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8920&quot;&gt;Rails patch to boost ActiveRecord#to_json with an options hash&lt;&#x2F;a&gt;. Yep much like what you can do with &lt;a href=&quot;http:&#x2F;&#x2F;api.rubyonrails.org&#x2F;classes&#x2F;ActiveRecord&#x2F;XmlSerialization.html#M000910&quot;&gt;&lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I hope it gets committed into the core some day. I mean, gosh, isn&#x27;t Rails all about Web 2.0 mashups. It even has that fancy &lt;code&gt;render :json&lt;&#x2F;code&gt; thing. I do believe JSON output needs to be treated more seriously in Rails rather than the half-hearted attempt at JSON encoding. No? Well, if the patch doesn&#x27;t get accepted I&#x27;ll still have &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;my plugin&lt;&#x2F;a&gt; (&lt;a href=&quot;#jsonifier-plugin&quot;&gt;see below&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, let&#x27;s see some examples:&lt;&#x2F;p&gt;
&lt;h3&gt;Some examples, see?&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming User and Post models where User has_many Posts:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david = User.find(1)
david.to_json  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No more &lt;code&gt;attributes&lt;&#x2F;code&gt; cruft!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;:only&lt;&#x2F;code&gt; and &lt;code&gt;:except&lt;&#x2F;code&gt; work the same way that as for &lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:only =&gt; :name)                 # {name: &quot;David&quot;}
david.to_json(:only =&gt; [:id, :name])          # {id: 1, name: &quot;David&quot;}
david.to_json(:except =&gt; :created_at)         # {id: 1, name: &quot;David&quot;, awesome: true}
david.to_json(:except =&gt; [:id, :created_at])  # {name: &quot;David&quot;, awesome: true}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can use the &lt;code&gt;:methods&lt;&#x2F;code&gt; options as well to include any methods on the object.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:methods =&gt; :permalink)
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, permalink =&gt; &quot;1-David&quot;}
david.to_json(:methods =&gt; [:permalink, :interestingness])
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #   permalink =&gt; &quot;1-David&quot;, :interestingness =&gt; 666}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;:include&lt;&#x2F;code&gt; option lets you include associations.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; :posts)
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{id: 1, author_id: 1, title: &quot;Welcome to the weblog&quot;}, \
  #            {id: 2, author_id: 1, title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;:only&lt;&#x2F;code&gt;, &lt;code&gt;:except&lt;&#x2F;code&gt;, and &lt;code&gt;:methods&lt;&#x2F;code&gt; works on the included associations as well:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; { :posts =&gt; { :only =&gt; :title } })
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{title: &quot;Welcome to the weblog&quot;}, \
  #            {title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, 2nd level (and higher order) associations work too:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;david.to_json(:include =&gt; { :posts =&gt; { \
                              :include =&gt; { :comments =&gt; { \
                                              :only =&gt; :body } }, \
                              :only =&gt; :title } })
  # {id: 1, name: &quot;David&quot;, awesome: true, created_at: &quot;07&#x2F;01&#x2F;2007&quot;, \
  #    posts: [{comments: [{body: &quot;1st post!&quot;}, {body: &quot;OMGWTFBBQ!&quot;}], \
  #             title: &quot;Welcome to the weblog&quot;}, \
  #            {comments: [{body: &quot;Don&#x27;t think too hard&quot;}], \
  #             title: &quot;So I was thinking&quot;}]}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Please do give any feedback at the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8920&quot;&gt;Rails patch for ActiveRecord#to_json&lt;&#x2F;a&gt; or here. I wanna know what you feel about adding this functionality into the Rails core!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jsonifier-plugin&quot;&gt;Jsonifier plugin&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve rolled the patch into a plugin: Jsonifier. The &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;Jsonifier Trac&lt;&#x2F;a&gt; is at &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Git repository:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier.git&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Github project page:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;http:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To install the plugin:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;ruby script&#x2F;plugin install git:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier.git&lt;&#x2F;code&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt; or &lt;code&gt;git clone&lt;&#x2F;code&gt; the repository manually into the &lt;code&gt;vendor&#x2F;plugins&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;h3&gt;A note on valid JSON&lt;&#x2F;h3&gt;
&lt;p&gt;The JSON Rails spits out by default is not strictly valid JSON since the &lt;a href=&quot;http:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc4627.txt?number=4627&quot;&gt;JSON specifications&lt;&#x2F;a&gt; require keys to be double quoted. To get strictly valid JSON, add&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActiveSupport::JSON.unquote_hash_key_identifiers = false&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;in your environment.rb (or in the Rails initializers directory if you&#x27;re on edge). See &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;06&#x2F;20&#x2F;how-to-get-strictly-valid-json-from-rails&#x2F;&quot;&gt;my blog post on how to get strictly valid JSON from Rails&lt;&#x2F;a&gt; for more info.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>How to get strictly valid JSON from Rails</title>
    <published>2007-06-20T11:47:59+00:00</published>
    <updated>2007-06-20T11:47:59+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/"/>
    <id>https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/06/20/how-to-get-strictly-valid-json-from-rails/">&lt;p&gt;&lt;ins&gt;Update: Edge Rails (and the forthcoming Rails 2.0) will emit only valid JSON. Read &lt;a href=&quot;&#x2F;2007&#x2F;10&#x2F;10&#x2F;new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity&#x2F;&quot;&gt;JSON serialization of ActiveRecord objects reaches maturity for more details&lt;&#x2F;a&gt;.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;ve worked with &lt;a href=&quot;http:&#x2F;&#x2F;www.json.org&#x2F;&quot;&gt;JSON&lt;&#x2F;a&gt; long enough in Rails, you&#x27;d probably have noticed that the JSON the convenient &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoders&#x2F;object.rb&quot;&gt;Object#to_json&lt;&#x2F;a&gt; method spits out is not strictly JSON-compliant (according to the &lt;a href=&quot;http:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc4627&quot;&gt;RFC 4627&lt;&#x2F;a&gt;, which states that object keys should be &quot;strings&quot;, and &quot;strings&quot; should be double-quoted). Here&#x27;s an example of what &lt;code&gt;to_json&lt;&#x2F;code&gt; produces when called on an ActiveRecord instance:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  id: 6589,
  code: &quot;SIN&quot;,
  name: &quot;Singapore&quot;,
  type: &quot;City&quot;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice how the keys (id, code, name, type) are not surrounded with double quotes. While this is generally not a problem if working purely in Rails, since Prototype and Rails itself can decode JSON like this, you&#x27;d run into problems with more finicky JSON parsers and decoders. PHP&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;php.net&#x2F;json_decode&quot;&gt;json_decode&lt;&#x2F;a&gt; is a perfect example - it demands that the object keys be double-quoted (or it fails to decode your JSON, silently returning NULL).&lt;&#x2F;p&gt;
&lt;p&gt;For a while I couldn&#x27;t figure out why Rails was doing it and &lt;a href=&quot;http:&#x2F;&#x2F;www.google.com.sg&#x2F;search?q=rails+invalid+json&quot;&gt;Google was of no help&lt;&#x2F;a&gt;. I decided to look at the Rails code since this can&#x27;t be a huge oversight on the Rails community, can it? Sure enough, I found the &quot;solution&quot; in the encoding portion of the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activesupport&#x2F;lib&#x2F;active_support&#x2F;json&#x2F;encoding.rb&quot;&gt;ActiveSupport::JSON&lt;&#x2F;a&gt; module:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
  # When +true+, Hash#to_json will omit quoting string or symbol keys
  # if the keys are valid JavaScript identifiers.  Note that this is
  # technically improper JSON (all object keys must be quoted), so if
  # you need strict JSON compliance, set this option to +false+.
  mattr_accessor :unquote_hash_key_identifiers
  @@unquote_hash_key_identifiers = true&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Doh! All that&#x27;s left to do is to put &lt;code&gt;ActiveSupport::JSON.unquote_hash_key_identifiers = false&lt;&#x2F;code&gt; in your &lt;code&gt;environment.rb&lt;&#x2F;code&gt; (or in the Rails initializers directory if you&#x27;re on edge) and your Rails app will start producing strictly valid JSON (and is friendlier to other non-Rails applications):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;{
  &quot;id&quot;: 6589,
  &quot;code&quot;: &quot;SIN&quot;,
  &quot;name&quot;: &quot;Singapore&quot;,
  &quot;type&quot;: &quot;City&quot;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;unquote_hash_key_identifiers&lt;&#x2F;code&gt; was added in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;5486&quot;&gt;changeset 5486&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>&#x27;Mac vs PC commercials&#x27;.gsub(&#x2F;Mac&#x2F;, &#x27;Rails&#x27;).gsub!(&#x2F;PC&#x2F;, &#x27;Java&#x27;)</title>
    <published>2007-05-15T00:22:19+00:00</published>
    <updated>2007-05-15T00:22:19+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/05/15/mac-vs-pc-commercialsgsubmac-railsgsubpc-java/"/>
    <id>https://chuyeow.wtf/2007/05/15/mac-vs-pc-commercialsgsubmac-railsgsubpc-java/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/05/15/mac-vs-pc-commercialsgsubmac-railsgsubpc-java/">&lt;p&gt;The &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;&quot;&gt;Rails Envy&lt;&#x2F;a&gt; guys have come up with &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;2007&#x2F;5&#x2F;14&#x2F;ruby-on-rails-commercial&quot;&gt;a spoof of the Mac versus PC commercials&lt;&#x2F;a&gt;. Yes, it&#x27;s Rails vs Java. &lt;a href=&quot;http:&#x2F;&#x2F;www.railsenvy.com&#x2F;2007&#x2F;5&#x2F;14&#x2F;ruby-on-rails-commercial&quot;&gt;Go watch it&lt;&#x2F;a&gt; or &lt;a href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=PQbuyKUaKFo&quot;&gt;catch it straight on YouTube&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Sexy migrations on Edge Rails</title>
    <published>2007-05-07T00:02:57+00:00</published>
    <updated>2007-05-07T00:02:57+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/05/07/sexy-migrations-on-edge-rails/"/>
    <id>https://chuyeow.wtf/2007/05/07/sexy-migrations-on-edge-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/05/07/sexy-migrations-on-edge-rails/">&lt;p&gt;So it seems &lt;a href=&quot;http:&#x2F;&#x2F;www.loudthinking.com&#x2F;&quot;&gt;DHH&lt;&#x2F;a&gt; was inspired by the &lt;a href=&quot;http:&#x2F;&#x2F;errtheblog.com&#x2F;post&#x2F;2381&quot;&gt;Sexy Migrations plugin&lt;&#x2F;a&gt; (which in turn was inspired by &lt;a href=&quot;http:&#x2F;&#x2F;hobocentral.net&#x2F;&quot;&gt;Hobo&lt;&#x2F;a&gt;) and committed &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6667?new_path=trunk&quot;&gt;changeset 6667&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now, you can do this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
create_table :products do |t| 
  t.integer :shop_id, :creator_id 
  t.string  :name, :value, :default =&gt; &quot;Untitled&quot;
  t.timestamps
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Succinct!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>If you&#x27;re having problems with script&#x2F;console on edge Rails...</title>
    <published>2007-04-11T10:27:56+00:00</published>
    <updated>2007-04-11T10:27:56+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/04/11/if-youre-having-problems-with-scriptconsole-on-edge-rails/"/>
    <id>https://chuyeow.wtf/2007/04/11/if-youre-having-problems-with-scriptconsole-on-edge-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/04/11/if-youre-having-problems-with-scriptconsole-on-edge-rails/">&lt;p&gt;If you&#x27;re on edge Rails and are having problems starting script&#x2F;console, it may be caused by spaces in your Rails working directory (see &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;7955&quot;&gt;ticket 7955: Console environment load broken when RAILS_ROOT contains spaces&lt;&#x2F;a&gt;). Basically the lack of quoting on RAILS_ROOT causes console.rb to pass incorrect paths to IRB (it gets split on the spaces in your directory path).&lt;&#x2F;p&gt;
&lt;p&gt;Just in case anyone runs into this problem and doesn&#x27;t want to start debugging the problem like I did. &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6512&quot;&gt;Changeset 6512&lt;&#x2F;a&gt; fixes things. If you do update Rails to revision 6512 (or higher) though, be aware of &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6507&quot;&gt;changest 6507&lt;&#x2F;a&gt;. Ahh the joys of living on the edge.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;site_ruby&#x2F;1.8&#x2F;rubygems&#x2F;custom_require.rb:27:in `gem_original_require&#x27;: no such file to load -- &#x2F;Data&#x2F;Working (LoadError)
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;site_ruby&#x2F;1.8&#x2F;rubygems&#x2F;custom_require.rb:27:in `require&#x27;
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;1.8&#x2F;irb&#x2F;init.rb:252:in `load_modules&#x27;
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;1.8&#x2F;irb&#x2F;init.rb:250:in `each&#x27;
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;1.8&#x2F;irb&#x2F;init.rb:250:in `load_modules&#x27;
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;1.8&#x2F;irb&#x2F;init.rb:21:in `setup&#x27;
        from &#x2F;opt&#x2F;local&#x2F;lib&#x2F;ruby&#x2F;1.8&#x2F;irb.rb:54:in `start&#x27;
        from &#x2F;opt&#x2F;local&#x2F;bin&#x2F;irb:13&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
  </entry>
  <entry>
    <title>Get your Rails tests results via Growl notifications</title>
    <published>2007-04-01T14:25:05+00:00</published>
    <updated>2007-04-01T14:25:05+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/"/>
    <id>https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/04/01/get-your-testing-results-via-growl-notifications/">&lt;p&gt;I&#x27;ve been using Autotest (part of the &lt;a href=&quot;http:&#x2F;&#x2F;www.zenspider.com&#x2F;ZSS&#x2F;Products&#x2F;ZenTest&#x2F;&quot;&gt;ZenTest&lt;&#x2F;a&gt; package) while testing my Rails applications and never thought of asking for more. After all, getting my tests (well, &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;&quot;&gt;specs&lt;&#x2F;a&gt; actually) run automatically whenever I make a relevant change &lt;em&gt;and&lt;&#x2F;em&gt; having &lt;code&gt;diff&lt;&#x2F;code&gt;-level granularity on which tests Autotest re-runs is pretty damn useful enough. That is, until I came across this &lt;a href=&quot;http:&#x2F;&#x2F;marcus.ahnve.net&#x2F;2007&#x2F;03&#x2F;30&#x2F;rspec-and-autotest&#x2F;&quot;&gt;RSpec and Autotest with Growl notifications blog entry&lt;&#x2F;a&gt; (on &lt;a href=&quot;http:&#x2F;&#x2F;javablogs.com&#x2F;&quot;&gt;JavaBlogs&lt;&#x2F;a&gt;, no less!)&lt;&#x2F;p&gt;
&lt;p&gt;How&#x27;re these for &lt;span style=&quot;color: #900;&quot;&gt;red&lt;&#x2F;span&gt;&#x2F;&lt;span style=&quot;color: #090;&quot;&gt;green&lt;&#x2F;span&gt; test results?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tests (specs) passing!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;growl-green-autotest.png&quot; alt=&quot;Growl notification of tests passing&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tests (specs) failing :(&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;growl-red-autotest.png&quot; alt=&quot;Growl notification of tests failing :(&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Much better! Now I don&#x27;t have to glance at my terminal window (I recently realized how painful it is while coding with a single monitor) and get unobtrusive notifications.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, this is Mac-only (or wherever &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;&quot;&gt;Growl&lt;&#x2F;a&gt; is supported). I had to follow links to several blog entries to get it setup nicely (see &lt;a href=&quot;http:&#x2F;&#x2F;blog.labratz.net&#x2F;articles&#x2F;2006&#x2F;09&#x2F;13&#x2F;growl-autotest-rails-with-zentest-3-4-0&quot;&gt;Growl + Autotest Rails with Zentest 3.4.0&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;blog.internautdesign.com&#x2F;2006&#x2F;11&#x2F;12&#x2F;autotest-growl-goodness&quot;&gt;Green goodness with autotest + growl&lt;&#x2F;a&gt; - those are my references).&lt;&#x2F;p&gt;
&lt;p&gt;Basically you need &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;&quot;&gt;Growl&lt;&#x2F;a&gt; installed, and the &lt;a href=&quot;http:&#x2F;&#x2F;growl.info&#x2F;documentation&#x2F;growlnotify.php&quot;&gt;&lt;code&gt;growlnotify&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; tool in your path. &lt;code&gt;growlnotify&lt;&#x2F;code&gt; can be found in the &lt;code&gt;Extras&#x2F;growlnotify&lt;&#x2F;code&gt; directory in the Growl dmg (for example, after you&#x27;ve mounted the Growl-0.x.x.dmg, you can find it here: &lt;code&gt;&#x2F;Volumes&#x2F;Growl&#x2F;Extras&#x2F;growlnotify&lt;&#x2F;code&gt;). Just copy the &lt;code&gt;growlnotify&lt;&#x2F;code&gt; executable into your path (I copied it into &lt;code&gt;&#x2F;opt&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; since I&#x27;m using Darwin Ports and don&#x27;t have a &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; directory). Verify it&#x27;s running by entering:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;growlnotify -m &quot;Testing growlnotify&quot; Boo Ya!&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;into a terminal window. You should see a Growl notification.&lt;&#x2F;p&gt;
&lt;p&gt;Now, you need to create an Autotest hook by creating an autotest init file in your home directory named &lt;code&gt;.autotest&lt;&#x2F;code&gt;, and copy this chunk of text in:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
module Autotest::Growl
  def self.growl title, msg, img, pri=0, sticky=&quot;&quot; 
    system &quot;growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}&quot; 
  end
&lt;p&gt;Autotest.add_hook :ran_command do |at|
output = at.results.last.slice(&#x2F;(\d+)\s.*specifications?,\s(\d+)\s.*failures?&#x2F;)
if output =~ &#x2F;[1-9]\sfailures?&#x2F;
growl &quot;Test Results&quot;, &quot;#{output}&quot;, &quot;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;rails_fail.png&quot;, 2, &quot;-s&quot;
else
growl &quot;Test Results&quot;, &quot;#{output}&quot;, &quot;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;rails_ok.png&quot;
end
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Replace the paths to the pass&#x2F;fail icons (as you can see, mine are in &lt;code&gt;&#x2F;Data&#x2F;Pictures&#x2F;Icons&#x2F;&lt;&#x2F;code&gt;) with the correct paths to any images you want to display (grab them from &lt;a href=&quot;http:&#x2F;&#x2F;blog.internautdesign.com&#x2F;2006&#x2F;11&#x2F;12&#x2F;autotest-growl-goodness&quot;&gt;Green goodness with autotest + growl&lt;&#x2F;a&gt; or roll your own). You can change the parameters passed to &lt;code&gt;growlnotify&lt;&#x2F;code&gt; however you want (use &lt;code&gt;growlnotify -h&lt;&#x2F;code&gt; to see what parameters it acccepts). The &lt;code&gt;pri&lt;&#x2F;code&gt; parameter sets the priority level of the message (test failures come up with a priority of 2, hence the red background of the Growl notification). Passing &lt;code&gt;-s&lt;&#x2F;code&gt; to &lt;code&gt;sticky&lt;&#x2F;code&gt; tells Growl to keep the notification sticky. If you&#x27;re running your (auto)tests on a remote server (e.g. in a Continuous Integration system), you can even use &lt;code&gt;growlnotify&lt;&#x2F;code&gt; to send remote notifications (see the &lt;code&gt;-H&lt;&#x2F;code&gt; switch) to your development workstations!&lt;&#x2F;p&gt;
&lt;p&gt;Lovely! I love you, MacBook Pro serial no. W86280NAVWW (despite your broken DVD drive and you randomly freezing up on me when you get too hot).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Testing rescue_action_in_public with RSpec</title>
    <published>2007-03-31T01:34:05+00:00</published>
    <updated>2007-03-31T01:34:05+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/31/testing-rescue_action_in_public-with-rspec/"/>
    <id>https://chuyeow.wtf/2007/03/31/testing-rescue_action_in_public-with-rspec/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/31/testing-rescue_action_in_public-with-rspec/">&lt;p&gt;After overriding &lt;code&gt;rescue_action_in_public&lt;&#x2F;code&gt; in the &lt;code&gt;ApplicationController&lt;&#x2F;code&gt; to deal with &lt;code&gt;ActiveRecord::RecordNotFound&lt;&#x2F;code&gt; exceptions (a very common exception to &lt;code&gt;rescue&lt;&#x2F;code&gt; in the canonical &#x27;show&#x27; actions of your controllers), I decided to test it. I&#x27;ve been getting used to &lt;acronym title=&quot;Behavior-Driven Developmen t&quot;&gt;BDD&lt;&#x2F;acronym&gt; with &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;&quot;&gt;RSpec&lt;&#x2F;a&gt; (and the &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;documentation&#x2F;rails&#x2F;index.html&quot;&gt;Spec::Rails plugin&lt;&#x2F;a&gt;), so I stumbled a bit when writing the spec.&lt;&#x2F;p&gt;
&lt;p&gt;I finally settled on this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
class DummyController &lt; ApplicationController
  def index
  end
end
&lt;p&gt;context &#x27;A child class of ApplicationController&#x27; do
controller_name :dummy&lt;&#x2F;p&gt;
&lt;p&gt;specify &#x27;should render a 404 error for ActiveRecord::RecordNotFound,
ActionController::UnknownController,
ActionController::UnknownAction,
ActionController::RoutingError exceptions (in public)&#x27; do&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;exceptions_404 = [
  ActionController::RoutingError.new(&amp;#39;test&amp;#39;),
  ActiveRecord::RecordNotFound.new,
  ActionController::UnknownController.new,
  ActionController::UnknownAction.new]

exceptions_404.each do |exception|
  controller.eigenclass.send(:define_method, :index) do
    raise exception.class, &amp;#39;some message&amp;#39;
  end

  lambda {
    get &amp;#39;index&amp;#39;
  }.should_raise(exception.class)
  controller.send :rescue_action_in_public, exception

  response.should be_missing
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice the use of a dummy controller so that we can actually make a request to it (and get all the Rails magic and environment set up ready for testing). Also, I had to use instances of the exceptions rather than their classes because I&#x27;m &lt;code&gt;send&lt;&#x2F;code&gt;ing a &lt;code&gt;rescue_action_in_public&lt;&#x2F;code&gt; message to the controller without knowing how to instantiate the exceptions (for example, &lt;code&gt;ActionController::RoutingError&lt;&#x2F;code&gt; actually has a constructor which requires at least 1 argument). So I create the exceptions first.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;eigenclass&lt;&#x2F;code&gt; method simply returns Ruby&#x27;s canonical singleton class or metaclass, depending on who you talk to (i.e. &lt;code&gt;class &amp;lt;&amp;lt; self; self; end;&lt;&#x2F;code&gt;) and I modify the dummy &#x27;index&#x27; action to raise the exception. And here&#x27;s the stinky part:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
lambda {
  get &#x27;index&#x27;
}.should_raise(exception.class)
controller.send :rescue_action_in_public, exception&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make a GET to the &#x27;index&#x27; action, make sure it raises the exception and catch it (with &lt;code&gt;should_raise&lt;&#x2F;code&gt; - the assertion is unnecessary since I did override &#x27;index&#x27; to raise the exception), and then force &lt;code&gt;rescue_action_in_public&lt;&#x2F;code&gt; to be called. Something&#x27;s fishy here - why isn&#x27;t the exception caught by default by &lt;code&gt;rescue_action_in_public&lt;&#x2F;code&gt;? I&#x27;ve set these to make sure that rescue_action_in_public is called but it seems like it never is called:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
ActionController::Base.consider_all_requests_local = false
controller.eigenclass.send(:define_method, :local_request?) do
  false
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I traced the code into ActionController::Rescue and everything seems to be in order. I&#x27;m stumped and weary, I think I&#x27;ll look at this again tomorrow. Anyone see any obvious mistakes?&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Checking for duplicate ActiveRecord objects</title>
    <published>2007-03-27T01:05:35+00:00</published>
    <updated>2007-03-27T01:05:35+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/27/checking-for-duplicate-activerecord-objects/"/>
    <id>https://chuyeow.wtf/2007/03/27/checking-for-duplicate-activerecord-objects/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/27/checking-for-duplicate-activerecord-objects/">&lt;p&gt;I&#x27;ve been writing a database importer plugin for a Rails application that needs to data on some &quot;legacy&quot; production databases (well, not really legacy, but the schema differs from ActiveRecord conventions) with the intention of scheduling a cron job to run the imports. Why not connect the Rails app to the legacy databases? Hmm, let&#x27;s see:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the records don&#x27;t have to be up to date (so I can afford to, say, import yesterday&#x27;s records today),&lt;&#x2F;li&gt;
&lt;li&gt;less jumping through hoops molding ActiveRecord models to the legacy databases,&lt;&#x2F;li&gt;
&lt;li&gt;the production database schema is liable to change - but this should not affect my Rails application,&lt;&#x2F;li&gt;
&lt;li&gt;there will be lower loads on the legacy databases which are in full-blown production use, and&lt;&#x2F;li&gt;
&lt;li&gt;most importantly, it gives me an excuse to figure out writing a data importer for a Rails application.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And I am surprised that it actually was rather fun writing the importer plugin (data importing stuff is normally one of the most unexciting things a programmer can do, right next to writing lengthy requirements documentation and any kind of contact sport). It&#x27;s basically a plugin that defines ActiveRecord models on the source (legacy) databases and then creates our Rails app&#x27;s models from these. Importer classes allow me to then run the imports using &lt;code&gt;script&#x2F;runner&lt;&#x2F;code&gt; like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
script&#x2F;runner &quot;HotelsImporter.import :start =&gt; 2.days.ago.to_date, :end =&gt; 1.day.ago.to_date&quot; -e production&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Put that in a cron job and there you go, scheduled daily (or hourly, whatever) imports.&lt;&#x2F;p&gt;
&lt;p&gt;But I digress. What was I actually going to talk about? Oh yes, checking for duplicate ActiveRecord objects. Now, the importers I wrote were run daily but there was the risk of re-importing the same data again (due to failed cron jobs, running the same job twice, acts of god, etc.). To be defensive, I needed to check that there were no existing records before importing them from the legacy databases.&lt;&#x2F;p&gt;
&lt;p&gt;At this point I could decide to run uniqueness checks on any natural keys of each table (and Rails makes this really easy with &lt;acronym title=&quot;ActiveRecord&quot;&gt;AR&lt;&#x2F;acronym&gt; validations, as we all know), or rely on a more convenient &quot;the whole hog&quot; field-by-field comparison. I settled on doing a field-by-field comparison after realizing that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;it&#x27;s easier and I don&#x27;t have to specify which natural fields constitute the natural keys, and&lt;&#x2F;li&gt;
&lt;li&gt;there are some tables which don&#x27;t really have a natural keys (these generally belong to has_many side of an association).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;ins&gt;Update: As choonkeat pointed out in a comment below, I can simply use &lt;code&gt;Post.find(:all, :conditions =&gt; new_post.attributes)&lt;&#x2F;code&gt; since that stood out very clearly as the way to do it. This was actually the first way I tried to do this but it didn&#x27;t work in the importer - I must have been doing something stupid! Doh! Thanks choonkeat for pointing out my blooper. Anyway you can mostly ignore what follows below but I&#x27;ll keep it here to remind myself of my error.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So I went looking for an easy way or a Railism to check whether an existing new ActiveRecord object already exists in the database. Hmm, I couldn&#x27;t find anything helpful - I guess everyone is relying on AR validations. Still, I went ahead and mixed in a &lt;code&gt;to_conditions&lt;&#x2F;code&gt; instance method to ActiveRecord::Base - looks like my answer to everything nowadays is to re-open existing classes.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
module Bezurk #:nodoc:
  module ActiveRecord #:nodoc:
    module Extensions
      def to_conditions
        attributes.inject({}) do |hash, (name, value)|
          hash.merge(name.intern =&gt; value)
        end
      end
      alias :to_conditions_hash :to_conditions
    end
  end
end
&lt;h1 id=&quot;&quot;&gt;...&lt;&#x2F;h1&gt;
&lt;p&gt;ActiveRecord::Base.send(:include, Bezurk::ActiveRecord::Extensions)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So now in my importers I can easily check for potential duplicate entries:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
new_post.save! if Post.find(:all, :conditions =&gt; new_post.to_conditions).empty?&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, I just have this nagging suspicion that there is a better way to do this...&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>irb and script&#x2F;console tab-completion</title>
    <published>2007-03-26T20:33:00+00:00</published>
    <updated>2007-03-26T20:33:00+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/26/irb-and-scriptconsole-tab-completion/"/>
    <id>https://chuyeow.wtf/2007/03/26/irb-and-scriptconsole-tab-completion/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/26/irb-and-scriptconsole-tab-completion/">&lt;p&gt;Ugh, I wish I found this earlier: &lt;a href=&quot;http:&#x2F;&#x2F;whytheluckystiff.net&#x2F;clog&#x2F;ruby&#x2F;tabCompletionInIRb.html&quot;&gt;Tab Completion in IRb&lt;&#x2F;a&gt;. I only went googling for this after I realized I have been tabbing to get auto-completion on &lt;code&gt;script&#x2F;console&lt;&#x2F;code&gt; for a bit but it never sunk in that tab-completion wasn&#x27;t ever working. Useful stuff, go set it up if you haven&#x27;t already.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>BarCamp Singapore Jan 2007</title>
    <published>2007-01-21T00:21:21+00:00</published>
    <updated>2007-01-21T00:21:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/"/>
    <id>https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/01/21/barcamp-singapore-jan-2007/">&lt;p&gt;I just got back from &lt;a href=&quot;http:&#x2F;&#x2F;barcamp.org&#x2F;BarCampSingapore&quot;&gt;BarCamp Singapore&lt;&#x2F;a&gt; a few hours ago. I was only vaguely familiar with the &lt;a href=&quot;http:&#x2F;&#x2F;barcamp.org&#x2F;TheRulesOfBarCamp&quot;&gt;Rules of BarCamp&lt;&#x2F;a&gt; prior to this, and actually only found out about the event from &lt;a href=&quot;http:&#x2F;&#x2F;blog.yanime.org&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; (of &lt;a href=&quot;http:&#x2F;&#x2F;rssfwd.com&#x2F;&quot;&gt;RssFwd&lt;&#x2F;a&gt; fame - check it out if you haven&#x27;t already) 2 days ago.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, props to the organizers for putting this together (especially the free BarCamp t-shirts from Yahoo!). Personally, I felt the icebreaker game took up too much time that could have been used for the sharing sessions - the tech track of sessions were crammed up towards the end of BarCamp.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;barcampsingapore.png&quot; alt=&quot;BarCamp Singapore logo&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notably, &lt;a href=&quot;http:&#x2F;&#x2F;poundbang.in&#x2F;&quot;&gt;Harish Mallipeddi&lt;&#x2F;a&gt;, who interned at &lt;a href=&quot;http:&#x2F;&#x2F;www.bezurk.com&#x2F;&quot;&gt;Bezurk&lt;&#x2F;a&gt; for a couple of months, shared with us an introduction to &lt;a href=&quot;http:&#x2F;&#x2F;www.djangoproject.com&#x2F;&quot;&gt;Django&lt;&#x2F;a&gt; together with some working code on a site he is working on. I didn&#x27;t know a whole lot about Django before and was impressed that there is a &quot;free&quot; admin application for Django applications. We (Choon Keat, Harish, and I) had a small debate over Django&#x27;s templating system (briefly, Django has it&#x27;s own templating system for its views, whereas Rails ERB is basically Ruby code mixed in HTML). To this day I am still convinced that PHP is already a templating language despite my old &lt;a href=&quot;http:&#x2F;&#x2F;www.sitepoint.com&#x2F;article&#x2F;smarty-php-template-engine&quot;&gt;Smarty card-carrying days&lt;&#x2F;a&gt;. Relating back to the Django templating system, Choon Keat and I didn&#x27;t like the idea of having to learn to use a templating language when the base language itself (Ruby or Python) would suffice. Obviously Python syntax wasn&#x27;t suitable for web designer consumption so Django had to come up with its own templating language.&lt;&#x2F;p&gt;
&lt;p&gt;Michael from &lt;a href=&quot;http:&#x2F;&#x2F;www.petrolwatch.com.sg&#x2F;&quot;&gt;PetrolWatch&lt;&#x2F;a&gt; showed us some flashy scriptaculous effects on his site and demoed the Ruby on Rails-inspired &lt;a href=&quot;http:&#x2F;&#x2F;www.cakephp.org&#x2F;&quot;&gt;CakePHP&lt;&#x2F;a&gt;. It&#x27;s a nice framework if you had to use PHP and performance is a concern (it&#x27;s true, Rails apps run more heavily than PHP scripts, and the difference in performance is very clear in servers with minimal resources). But the lack of a good testing framework was discouraging. Still, I must say I&#x27;d have used it (or a similiar framework) if Rails didn&#x27;t exist or if I was tied to using PHP for web development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;blog.yanime.org&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; showed the non-believers the power of Rails&#x27; &lt;code&gt;script&#x2F;console&lt;&#x2F;code&gt; as well as the flexibility of Ruby in allowing developers to make their own extensions to existing classes (aka &quot;who needs hooks from God?&quot;). I probably should have stepped in and showed some basic Rails migrations stuff that would have impressed (hopefully) the Django and CakePHP fanbase (all 2 of them) - but my laptop was running out of battery (and I was shy).&lt;&#x2F;p&gt;
&lt;p&gt;Oh and I saw a good number of Macs there, and at least 3 laptops running a Linux distro of some sort. Cool.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>RubyGems 0.9.1 - required update</title>
    <published>2007-01-20T23:02:35+00:00</published>
    <updated>2007-01-20T23:02:35+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/01/20/rubygems-091-required-update/"/>
    <id>https://chuyeow.wtf/2007/01/20/rubygems-091-required-update/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/01/20/rubygems-091-required-update/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;blog.segment7.net&#x2F;articles&#x2F;2007&#x2F;01&#x2F;18&#x2F;rubygems-0-9-1&quot;&gt;RubyGems has been updated to 0.9.1&lt;&#x2F;a&gt; and is a required update due to a security issue. The blog announcement reveals more:&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;The most important change in RubyGems 0.9.1 is that RubyGems no longer allows files to be installed outside of the installation directory.&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;It&#x27;s a required update as the RubyForge gem repository will soon disallow installation of gems if you have an older version of RubyGems.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, a new feature I found very useful is &lt;code&gt;gem outdated&lt;&#x2F;code&gt;, which lists the gems you have installed that are currently not the latest versions (I just realized that mongrel is actually already up to 1.0 RC!). And don&#x27;t forget multiple gem uninstallation with &lt;code&gt;gem uninstall&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Update your RubyGems by running:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;gem update --system&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
  </entry>
  <entry>
    <title>Adding full text search to your Rails app in 1 hour and 10 lines of code</title>
    <published>2006-12-04T19:19:17+00:00</published>
    <updated>2006-12-04T19:19:17+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/12/04/adding-full-text-search-to-your-rails-app-in-1-hour-and-10-lines-of-code/"/>
    <id>https://chuyeow.wtf/2006/12/04/adding-full-text-search-to-your-rails-app-in-1-hour-and-10-lines-of-code/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/12/04/adding-full-text-search-to-your-rails-app-in-1-hour-and-10-lines-of-code/">&lt;p&gt;Yup, it&#x27;s that fast and simple, using &lt;a href=&quot;http:&#x2F;&#x2F;ferret.davebalmain.com&#x2F;trac&#x2F;wiki&quot;&gt;Ferret&lt;&#x2F;a&gt;, a Ruby port of &lt;a href=&quot;http:&#x2F;&#x2F;lucene.apache.org&#x2F;&quot;&gt;Lucene&lt;&#x2F;a&gt; (the de facto full text search engine written in Java) and the &lt;a href=&quot;http:&#x2F;&#x2F;projects.jkraemer.net&#x2F;acts_as_ferret&#x2F;wiki&quot;&gt;acts_as_ferret&lt;&#x2F;a&gt; plugin, I added &quot;Did you mean this?&quot; functionality to a &lt;a href=&quot;http:&#x2F;&#x2F;rails.bezurk.net:3000&#x2F;affiliates&#x2F;hotels&#x2F;search&quot;&gt;small Rails application&lt;&#x2F;a&gt; (non-perma link) today rather quickly and painlessly.&lt;&#x2F;p&gt;
&lt;h3&gt;Adding full text search funtionality to your Rails applications&lt;&#x2F;h3&gt;
&lt;p&gt;Install &lt;a href=&quot;http:&#x2F;&#x2F;ferret.davebalmain.com&#x2F;trac&#x2F;wiki&quot;&gt;Ferret&lt;&#x2F;a&gt; via RubyGems.&lt;br &#x2F;&gt;
&lt;code&gt;sudo gem install ferret&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Install the &lt;a href=&quot;http:&#x2F;&#x2F;projects.jkraemer.net&#x2F;acts_as_ferret&#x2F;wiki&quot;&gt;acts_as_ferret&lt;&#x2F;a&gt; plugin for your Rails application.&lt;br &#x2F;&gt;
&lt;code&gt;ruby script&#x2F;plugin install &amp;lt;ACTS_AS_FERRET_SVN_REPOSITORY&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Add the acts_as_ferret mixin method to your ActiveRecord model, specifying the fields you want indexed.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;class Location &lt; ActiveRecord::Base
  belongs_to :country, :foreign_key =&gt; &#x27;country_code&#x27;
  belongs_to :state
&lt;p&gt;acts_as_ferret :fields =&amp;gt; [:location_name, :country_name, :state_name]&lt;&#x2F;p&gt;
&lt;p&gt;def country_name
country.country_name
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you have any associations that you want searched as well, one way (there is more than one way to do this) would be like what I did above with the country_name attribute of Country. For a more detailed discussion on Ferret and ActiveRecord associations, I found &lt;a href=&quot;http:&#x2F;&#x2F;www.ruby-forum.com&#x2F;topic&#x2F;86741&quot;&gt;this thread in the Ruby forum&lt;&#x2F;a&gt; enlightening.&lt;&#x2F;p&gt;
&lt;p&gt;In your controller, use Model.find_by_contents() to perform the full text search with your query. If you need fuzzy matching, append a tilde (&quot;~&quot;) to the end of your query - if you&#x27;re here, you probably needed fuzzy matching anyway as you&#x27;re most likely creating &quot;Did you mean this?&quot;-type functionality.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# In the controller...
@locations = Location.find_by_contents(&quot;#{@search_request.location_entered}~&quot;) # The &quot;~&quot; is for fuzzy matching.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All that&#x27;s left is to flash the appropriate message in your view and display your model objects as you normally would.&lt;&#x2F;p&gt;
&lt;p&gt;Some &lt;strong&gt;gotchas&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If you change the way your model is indexed, remember to clear out the existing one. acts_as_ferret stores the index by default in a &#x27;index&#x2F;&#x27; directory in the root of your Rails application. Stop your mongrel&#x2F;Webrick process to remove the lock on the index files and delete the whole directory - Ferret will rebuild it the next time you perform a full text search.&lt;&#x2F;li&gt;
&lt;li&gt;The first time you do a full text search, Ferret builds your index for you and this takes quite a while - don&#x27;t be alarmed if your Rails application appears for freeze or returns a 500 internal server error. You can observe the contents of the &#x27;index&#x2F;&#x27; directory in the root of your Rails application to tell when Ferret has finished indexing (files stop appearing and disappearing). I found it easier to run a &#x27;find_by_contents&#x27; call on my models via &#x27;script&#x2F;console&#x27; and waiting for some results to appear.&lt;&#x2F;li&gt;
&lt;li&gt;Append a &quot;~&quot; to your query string for fuzzy matching! This allows you to retrieve results matching phonetically or are mispelled. There are more complex matching rules - check out the Lucene documentation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
  </entry>
  <entry>
    <title>Excluding specific tests with rake</title>
    <published>2006-09-05T20:36:46+00:00</published>
    <updated>2006-09-05T20:36:46+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/09/05/excluding-specific-tests-with-rake/"/>
    <id>https://chuyeow.wtf/2006/09/05/excluding-specific-tests-with-rake/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/09/05/excluding-specific-tests-with-rake/">&lt;p&gt;Sometimes, I just want to skip just that one test when I run my tests with &lt;code&gt;rake test&lt;&#x2F;code&gt; because it takes much longer than other tests, and it gets in the way of rapid iterative cycles when coding. I looked around and haven&#x27;t found a way to do that with &lt;a href=&quot;http:&#x2F;&#x2F;rake.rubyforge.org&#x2F;&quot;&gt;rake&lt;&#x2F;a&gt;, so I set down to writing a custom rake task.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;namespace :test do
  namespace :units do
    Rake::TestTask.new(:excluding =&gt; &#x27;db:test:prepare&#x27;) do |t|
      if ENV[&#x27;THESE&#x27;]
        def t.file_list
          exclusion_patterns = ENV[&#x27;THESE&#x27;].split(&#x27;,&#x27;)
          unit_tests = FileList[&#x27;test&#x2F;unit&#x2F;**&#x2F;*_test.rb&#x27;].select do |path|
            excluded = exclusion_patterns.select { |excl| &#x2F;#{excl}&#x2F;.match(path) }
            p &quot;Excluding #{path}&quot; if not excluded.empty?
            excluded.empty?
          end
        end
      else
        p &#x27;Running all unit tests (specify THESE=&quot;pattern1, pattern2&quot; to exclude files)&#x27;
        t.pattern = &#x27;test&#x2F;unit&#x2F;**&#x2F;*_test.rb&#x27;
      end
      t.libs &lt;&lt; &#x27;test&#x27;
      t.verbose = true
    end
    Rake::Task[&#x27;test:units:excluding&#x27;].comment = &#x27;Run unit tests with exclusions (specify exclusions with THESE=&quot;pattern1,pattern2&quot;)&#x27;
  end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, &lt;code&gt;rake test:recent&lt;&#x2F;code&gt; and &lt;code&gt;rake test:uncommitted&lt;&#x2F;code&gt; would suffice for most purposes, but there are times when I just want to not run that a particular test or tests because they just take too long (and by definition, get in the way) and I&#x27;m pretty sure they won&#x27;t be broken. (Always run all the tests before a commit though, don&#x27;t be naughty.)&lt;&#x2F;p&gt;
&lt;p&gt;You can run the task like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;rake test:units:excluding THESE=&quot;item_test,atte\w*&quot;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;ins&gt;Update: As it turns out, the task descriptions weren&#x27;t being set correctly. &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;railties&#x2F;lib&#x2F;tasks&#x2F;testing.rake?rev=5016&quot;&gt;Revision 5016&lt;&#x2F;a&gt; fixes this so &lt;code&gt;rake -T&lt;&#x2F;code&gt; shows the task descriptions properly.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Ruby on Rails satire blog</title>
    <published>2006-08-14T20:06:59+00:00</published>
    <updated>2006-08-14T20:06:59+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/14/ruby-on-rails-satire-blog/"/>
    <id>https://chuyeow.wtf/2006/08/14/ruby-on-rails-satire-blog/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/14/ruby-on-rails-satire-blog/">&lt;h4&gt;Javac programmers are Very Slow and he is Agile&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;railsblob.blogspot.com&#x2F;&quot;&gt;My Rails Blob&lt;&#x2F;a&gt; pokes fun at the cult of Ruby on Rails via satire. Recommended blog posts: &lt;a href=&quot;http:&#x2F;&#x2F;railsblob.blogspot.com&#x2F;2006&#x2F;08&#x2F;rubby-links-on-ww-w.html&quot;&gt;Rubby Links on the W.W. w.&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;railsblob.blogspot.com&#x2F;2006&#x2F;08&#x2F;upgradeing-rails-securiety-through.html&quot;&gt; Upgradeing Rails: Securiety through Obscenity&lt;&#x2F;a&gt; [&lt;em&gt;sic&lt;&#x2F;em&gt;]. I&#x27;ve subscribed to the RSS feed.&lt;&#x2F;p&gt;
&lt;h4&gt;NO! - Bad User!!!&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;thedailywtf.com&#x2F;&quot;&gt;The Daily WTF&lt;&#x2F;a&gt; has this monthly collection of hilarious pop-up error blunders, and as usual this month&#x27;s a gem: &lt;a href=&quot;http:&#x2F;&#x2F;thedailywtf.com&#x2F;forums&#x2F;thread&#x2F;85750.aspx&quot;&gt;Pop-up Potpourri: Announced By God&lt;&#x2F;a&gt;. Must read.&lt;&#x2F;p&gt;
&lt;p&gt;Developers would find this particularly funny (I did):&lt;&#x2F;p&gt;
&lt;div class=&quot;image&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;wtf2.jpg&quot; alt=&quot;Bad user!&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And this one&#x27;s for my boss, Gary (remember the &#x27;Abort&#x2F;Retry&#x2F;Ignore&#x27; you saw at the MRT station?)&lt;&#x2F;p&gt;
&lt;div class=&quot;image&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;lite.jpg&quot; alt=&quot;Next stop: null&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
</content>
  </entry>
  <entry>
    <title>Extract Any Archive with Ruby, Slimtimer, Feedalizer</title>
    <published>2006-08-12T19:58:06+00:00</published>
    <updated>2006-08-12T19:58:06+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/12/extract-any-archive-with-ruby-slimtimer-feedalizer/"/>
    <id>https://chuyeow.wtf/2006/08/12/extract-any-archive-with-ruby-slimtimer-feedalizer/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/12/extract-any-archive-with-ruby-slimtimer-feedalizer/">&lt;p&gt;A bunch of cool stuff I found over the weekend that didn&#x27;t individually deserve a blog post, but I thought would be worth sharing.&lt;&#x2F;p&gt;
&lt;h4&gt;Extract Any Archive with Ruby&lt;&#x2F;h4&gt;
&lt;p&gt;This is really neat if you could never remember what commands or command-line arguments you need to extracting archives (.zip, .tar.gz, .tar.bz2 - those kinds of archives).&lt;&#x2F;p&gt;
&lt;p&gt;With this &lt;a href=&quot;http:&#x2F;&#x2F;martin.ankerl.org&#x2F;2006&#x2F;08&#x2F;11&#x2F;program-e-extract-any-archive&#x2F;&quot;&gt;Extract Any Archive&lt;&#x2F;a&gt; script written in Ruby, instead of&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;tar jxvf DonkeyPr0n.tar.bz2&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;you can simply do&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;e DonkeyPr0n.tar.bz2&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instant gratification!&lt;&#x2F;p&gt;
&lt;h4&gt;Slim Timer&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.slimtimer.com&#x2F;&quot;&gt;SlimTimer&lt;&#x2F;a&gt; is one another of those productivity-keep-track-of-your-todo-list type applications - I like it because seeing the time ticking away gets you motivated on sticking to the task at hand. You can stick it into your Firefox sidebar and all that AJAX-y stuff makes it behave like a normal application.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;slim-timer-firefox-sidebar.png&quot; alt=&quot;SlimTimer running in a Firefox Web panel&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4&gt;Feedalizer - transform web pages into RSS feeds&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;blog.yanime.org&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; pointed this out to me recently: &lt;a href=&quot;http:&#x2F;&#x2F;termos.vemod.net&#x2F;feedalizer&quot;&gt;Feedalizer&lt;&#x2F;a&gt; (backed by &lt;a href=&quot;http:&#x2F;&#x2F;code.whytheluckystiff.net&#x2F;hpricot&#x2F;&quot;&gt;Hpricot&lt;&#x2F;a&gt;). I played around with it and it was so easy (and fun) to use. Whipped up a &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;mongrel.xml&quot;&gt;Mongrel news feed&lt;&#x2F;a&gt; (&lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;mongrel-news-feed.rb-txt&quot;&gt;code&lt;&#x2F;a&gt;) for &lt;a href=&quot;http:&#x2F;&#x2F;mongrel.rubyforge.org&#x2F;news.html&quot;&gt;Mongrel news&lt;&#x2F;a&gt; (which didn&#x27;t have an RSS feed). The hardest part was figuring out which Hpricot methods to use to parse the bits I needed.&lt;&#x2F;p&gt;
&lt;h4&gt;Served by Apache 2.2, mod_proxy_balancer, and Mongrel&lt;&#x2F;h4&gt;
&lt;p&gt;I got off my butt and set up Apache 2.2 with mod_proxy_balancer to load-balance a cluster of Mongrel processes, if you&#x27;re still seeing this, that means it hasn&#x27;t crashed, yet :p. Just kidding heh - I&#x27;m finding this setup pretty stable, though there was once the mongrel processes seem to have been over-loaded with requests (with 96MB RAM I can only run 2 processes, and even then I run out of memory real fast due to automated comment spam - does anyone have any solutions to blocking automated comment spammers before they even hit your website?).&lt;&#x2F;p&gt;
&lt;p&gt;In any case, I learnt quite a bit as I was setting up my deployment environment for Rails, and hopefully someone will be able to benefit from that when I finish my post on the topic.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 1.1.5 (security patch)</title>
    <published>2006-08-10T19:46:24+00:00</published>
    <updated>2006-08-10T19:46:24+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/10/rails-115-security-patch/"/>
    <id>https://chuyeow.wtf/2006/08/10/rails-115-security-patch/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/10/rails-115-security-patch/">&lt;p&gt;For anyone who cares or who runs a production site on Rails, &lt;acronym title=&quot;David Heinemeier Hansson&quot;&gt;DHH&lt;&#x2F;acronym&gt; just announced &lt;a href=&quot;http:&#x2F;&#x2F;wrath.rubyonrails.org&#x2F;pipermail&#x2F;rails&#x2F;2006-August&#x2F;059776.html&quot;&gt;the release of Rails 1.1.5 with an undisclosed security patch&lt;&#x2F;a&gt;. Time to&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;gem install rails&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and update your config&#x2F;environment.rb to use the Rails 1.1.5&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# Specifies gem version of Rails to use when
# vendor&#x2F;rails is not present
RAILS_GEM_VERSION = &#x27;1.1.5&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
  </entry>
  <entry>
    <title>Easy introspection in Ruby</title>
    <published>2006-08-09T19:43:40+00:00</published>
    <updated>2006-08-09T19:43:40+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/09/easy-introspection-in-ruby/"/>
    <id>https://chuyeow.wtf/2006/08/09/easy-introspection-in-ruby/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/09/easy-introspection-in-ruby/">&lt;p&gt;Just some notes on reflection and introspection in Ruby&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
someString = &#x27;http:&#x2F;&#x2F;google.com&#x27;
&lt;h1 id=&quot;print-the-object-s-class-methods-superclass-and&quot;&gt;Print the object&#x27;s class, methods, superclass and&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;ancestors-mixins-and-superclasses&quot;&gt;ancestors (mixins and superclasses),&lt;&#x2F;h1&gt;
&lt;p&gt;p someString.class
p someString.methods
p someString.class.superclass
p someString.class.ancestors&lt;&#x2F;p&gt;
&lt;h1 id=&quot;print-the-methods-of-the-string-class&quot;&gt;Print the methods of the String class.&lt;&#x2F;h1&gt;
&lt;p&gt;p String.private_instance_methods(false)
p String.public_instance_methods(false)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pass-true-to-recurse-into-parent-classes&quot;&gt;Pass true to recurse into parent classes.&lt;&#x2F;h1&gt;
&lt;p&gt;p String.public_instance_methods(true)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;calling-instance-methods-with-send&quot;&gt;Calling instance methods with send().&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;Random text&quot;.send(:length) # 11
-23.send(:succ) # 22&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-method-objects-and-call&quot;&gt;Using Method objects and call().&lt;&#x2F;h1&gt;
&lt;p&gt;length_method = &quot;Random text&quot;.method(:length)
length_method.call # 11&lt;&#x2F;p&gt;
&lt;h1 id=&quot;another-way-using-eval&quot;&gt;Another way, using eval().&lt;&#x2F;h1&gt;
&lt;p&gt;length_method = %q{&quot;Random text&quot;.length}
eval length_method
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Check out &lt;a href=&quot;http:&#x2F;&#x2F;www.chadfowler.com&#x2F;ruby&#x2F;drb.html&quot;&gt;Distributed Ruby (DRb)&lt;&#x2F;a&gt;: it&#x27;s a very neat, non-fancy way of exposing object methods as remote services.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>From Wordpress 2 to Typo 4</title>
    <published>2006-08-06T19:33:05+00:00</published>
    <updated>2006-08-06T19:33:05+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/06/from-wordpress-2-to-typo-4/"/>
    <id>https://chuyeow.wtf/2006/08/06/from-wordpress-2-to-typo-4/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/06/from-wordpress-2-to-typo-4/">&lt;p&gt;It was a slow day so I decided to cross one thing off my to-do list, and that&#x27;s getting &lt;a href=&quot;http:&#x2F;&#x2F;www.typosphere.org&#x2F;&quot;&gt;Typo&lt;&#x2F;a&gt; installed and migrating from WordPress. I&#x27;ve been looking at getting Typo installed for awhile ever since I saw (and liked) its AJAX-y comments form, plus &lt;a href=&quot;http:&#x2F;&#x2F;www.typosphere.org&#x2F;trac&#x2F;wiki&#x2F;DownloadStable&quot;&gt;Typo 4&lt;&#x2F;a&gt; being just released did help.&lt;&#x2F;p&gt;
&lt;p&gt;The install went straightforward enough, though I didn&#x27;t get to try out the new installer gem. I didn&#x27;t bother because I&#x27;m on a Dreamhost shared hosting account, though &lt;a href=&quot;http:&#x2F;&#x2F;scottstuff.net&#x2F;blog&#x2F;articles&#x2F;2006&#x2F;07&#x2F;28&#x2F;how-to-install-gems-when-youre-not-root&quot;&gt;installing the gem without root privileges&lt;&#x2F;a&gt; seems like it should work. I simply followed this &lt;a href=&quot;http:&#x2F;&#x2F;blog.aidenbordner.com&#x2F;articles&#x2F;2006&#x2F;07&#x2F;24&#x2F;getting-typo-4-0-0-running-on-dreamhost&quot;&gt;guide to getting Typo 4 running on Dreamhost&lt;&#x2F;a&gt;. Ran into some trouble running the Wordpress import script (found in &#x2F;db&#x2F;converters&#x2F;wordpress2.rb), but Google turned up &lt;a href=&quot;http:&#x2F;&#x2F;www.typosphere.org&#x2F;trac&#x2F;ticket&#x2F;1053&quot;&gt;the solution&lt;&#x2F;a&gt; (basically a patch to the Articles model that tries to send pings when importing posts). This should already be fixed in Typo SVN, but it&#x27;s not in release 4.0.&lt;&#x2F;p&gt;
&lt;p&gt;Anyhow, Typo seems spiffy, though I am still getting the occasional &quot;Application Error&quot;, but that&#x27;s most likely a Dreamhost thing. Liking the near-minimalist theme as well - I&#x27;m already missing the green clover though heh.&lt;&#x2F;p&gt;
&lt;p&gt;Things I&#x27;m already liking:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sidebar modules that you can add to your blog - for example, getting the del.icio.us links I have at the side to show is just a matter of dragging the del.icio.us sidebar item to the &quot;Active&quot; list and pointing it to my del.icio.us feed. There&#x27;re sidebar items for Flickr, tags, 43things, Amazon, and even the categories and archives are sidebar items.
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;typo-sidebar.png&quot; alt=&quot;Screenshot of Typo 4&#x27;s sidebar items administration&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;A Blacklist section where you can enter blacklisted words and &lt;strong&gt;regexes&lt;&#x2F;strong&gt;! Take that texas holdem poker!&lt;&#x2F;li&gt;
&lt;li&gt;Live preview of your posts as you type - can get a little sluggish though.&lt;&#x2F;li&gt;
&lt;li&gt;The ability to search and delete all comments - Wordpress was missing that and running SQL statements in phpmyadmin stopped being fun.&lt;&#x2F;li&gt;
&lt;li&gt;The nice &lt;a href=&quot;http:&#x2F;&#x2F;quotedprintable.com&#x2F;pages&#x2F;scribbish&quot;&gt;Scribbish theme&lt;&#x2F;a&gt; that comes with the Typo package.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Things that I don&#x27;t like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Linking to uploaded files was confusing. I like the whole &quot;Attachments&quot; idea, but I didn&#x27;t know how to link to them until I browsed to the Resources section and copied the link to the image I just uploaded (by saving the post I was making - there wasn&#x27;t a way to upload an attachment while writing the post).
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;typo-attachments.png&quot; alt=&quot;Screenshot of Typo Attachments feature&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m probably doing things the wrong way though, seeing as this is way too obtuse. Would be nice to see improvements (such as, upload file as you write your post, click on uploaded file to include into post, all on the same page with AJAX).&lt;&#x2F;li&gt;
&lt;li&gt;Um, nothing further!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Need to use it more to decide whether I&#x27;ll like this or not.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>RSpec and BDD</title>
    <published>2006-08-05T16:08:33+00:00</published>
    <updated>2006-08-05T16:08:33+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/05/rspec-and-bdd/"/>
    <id>https://chuyeow.wtf/2006/08/05/rspec-and-bdd/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/05/rspec-and-bdd/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;&quot;&gt;RSpec&lt;&#x2F;a&gt;: Behavior Driven Development framework for Ruby. It&#x27;s like writing your specifications in English that&#x27;s executable. &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;tools&#x2F;index.html&quot;&gt;Eight tools in one&lt;&#x2F;a&gt;, and a really nice &lt;a href=&quot;http:&#x2F;&#x2F;rspec.rubyforge.org&#x2F;documentation&#x2F;mocks.html&quot;&gt;Mock Objects framework&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
</feed>
