<?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-on-rails/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://chuyeow.wtf"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  <updated>2010-06-14T11:22:50+00:00</updated>
  <id>https://chuyeow.wtf/categories/ruby-on-rails/feed.xml</id>
  <entry>
    <title>Rendering plists from your Rails app</title>
    <published>2010-06-14T11:22:50+00:00</published>
    <updated>2010-06-14T11:22:50+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2010/06/14/rendering-plists-from-your-rails-app/"/>
    <id>https://chuyeow.wtf/2010/06/14/rendering-plists-from-your-rails-app/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2010/06/14/rendering-plists-from-your-rails-app/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;jeena&#x2F;&quot;&gt;Jeena&lt;&#x2F;a&gt; emailed me recently about his Rails plugin, &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;jeena&#x2F;plistifier&quot;&gt;plistifier&lt;&#x2F;a&gt;, that allows you to render &lt;a href=&quot;http:&#x2F;&#x2F;developer.apple.com&#x2F;mac&#x2F;library&#x2F;documentation&#x2F;Cocoa&#x2F;Conceptual&#x2F;PropertyLists&#x2F;Introduction&#x2F;Introduction.html&quot;&gt;plists&lt;&#x2F;a&gt; (property lists).&lt;&#x2F;p&gt;
&lt;p&gt;It allows you to render your ActiveRecord objects as plists (among other things):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def show
  @post = Post.find(params[:id])
&lt;p&gt;respond_to do |format|
format.xml   { render :xml =&amp;gt; @post }
format.plist { render :plist =&amp;gt; @post }
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Jeena was kind enough to let me know he &quot;stole&quot; my old &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;07&#x2F;11&#x2F;better-json-output-from-rails-with-the-jsonifier-plugin&#x2F;&quot;&gt;Jsonifier plugin&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;chuyeow&#x2F;jsonifier&quot;&gt;github&lt;&#x2F;a&gt;) code in &lt;a href=&quot;http:&#x2F;&#x2F;github.com&#x2F;jeena&#x2F;plistifier&quot;&gt;plistifier&lt;&#x2F;a&gt;.&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>RailsConf 2008 Day 1 - pics and a summary</title>
    <published>2008-05-30T13:32:11+00:00</published>
    <updated>2008-05-30T13:32:11+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/05/30/railsconf-2008-day-1-pics-and-a-summary/"/>
    <id>https://chuyeow.wtf/2008/05/30/railsconf-2008-day-1-pics-and-a-summary/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/05/30/railsconf-2008-day-1-pics-and-a-summary/">&lt;p&gt;Day 1 of &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;content&#x2F;home&quot;&gt;RailsConf 2008&lt;&#x2F;a&gt; was basically tutorial day (&lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;grid?date=2008-05-29&quot;&gt;schedule&lt;&#x2F;a&gt;) and started with my colleague here with me, &lt;a href=&quot;http:&#x2F;&#x2F;arunthampi.wordpress.com&#x2F;&quot;&gt;Arun&lt;&#x2F;a&gt;, missing out on &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;detail&#x2F;4417&quot;&gt;Yoga on Rails&lt;&#x2F;a&gt; and me sleeping until the first tutorial session. Anyway, I snapped some photos while trying to remain the unobtrusive tourist.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a shot of Portland Convention Center where it&#x27;s all happening:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;portland-convention-center-twin-peaks.jpg&quot; alt=&quot;Portland Convention Center - twin peaks outside&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;There&#x27;re queues for collection of badges after registering your attendance:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;railsconf-day-1-registration-3.jpg&quot; alt=&quot;RailsConf Day 1 - registration queue&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;Patience in the queue rewarded me with a RailsConf badge&#x2F;name tag:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;railsconf-badge.jpg&quot; alt=&quot;RailsConf badge&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 was at the &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;detail&#x2F;1862&quot;&gt;Meta-programming Ruby for Fun &amp;amp; Profit&lt;&#x2F;a&gt; tutorial in the morning. I think when I selected the tutorial it was before I&#x27;d seen Neal Ford and Patrick Farley&#x27;s (the speakers) presentation videos from elsewhere - I know &lt;a href=&quot;http:&#x2F;&#x2F;mtnwestrubyconf2008.confreaks.com&#x2F;11farley.html&quot;&gt;Patrick presented at MWRC&lt;&#x2F;a&gt; and enjoyed that video.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;railsconf-day-1-metaprogramming-tutorial-1.jpg&quot; alt=&quot;RailsConf day 1 - metaprogramming tutorial&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;So anyway, after the break I went over to the &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;detail&#x2F;1962&quot;&gt;Refactoring Your Rails Application&lt;&#x2F;a&gt; tutorial. Was pretty good, but I didn&#x27;t learn much I didn&#x27;t already know.&lt;&#x2F;p&gt;
&lt;p&gt;Lunch came in the form of a pretty box:&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;railsconf-day-1-lunch.jpg&quot; alt=&quot;RailsConf day 1 - lunch&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;After lunch was the 2nd tutorial session and I went to both &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;detail&#x2F;2072&quot;&gt;CI for the Rails Guy (or Gal)&lt;&#x2F;a&gt; (by Chad Woolley) and &lt;a href=&quot;http:&#x2F;&#x2F;en.oreilly.com&#x2F;rails2008&#x2F;public&#x2F;schedule&#x2F;detail&#x2F;1993&quot;&gt;Developer Testing Tricks&lt;&#x2F;a&gt; (by Brian Takita). There were some scathing comments about how the tutorials were rather underwhelming so far in &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;railsconf&quot;&gt;#railsconf&lt;&#x2F;a&gt; on IRC. While I agree that the tutorials were rather underwhelming, I think I should have expected it. Oh well, I&#x27;ll know to skip them next time.&lt;&#x2F;p&gt;
&lt;p&gt;Later that night, at the Birds of a Feather session, after stealing a &lt;a href=&quot;http:&#x2F;&#x2F;www.pivotalabs.com&#x2F;&quot;&gt;Pivotal Labs t-shirt&lt;&#x2F;a&gt; (they&#x27;re launching a bug tracker, project management type app called &lt;a href=&quot;http:&#x2F;&#x2F;www.pivotaltracker.com&#x2F;&quot;&gt;Pivotal Tracker&lt;&#x2F;a&gt; at RailsConf), Yehuda Katz (Merb and jQuery ninja) gave a presentation on Merb (geared towards Rails folks). It was a pretty interesting talk though there wasn&#x27;t much above what Ezra had &lt;a href=&quot;http:&#x2F;&#x2F;goruco2008.confreaks.com&#x2F;06_zygmuntowicz.html&quot;&gt;presented previously at GoRuCo 2008&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;mwrc2008.confreaks.com&#x2F;02zygmuntowicz.html&quot;&gt;at MWRC 2008&lt;&#x2F;a&gt; (I think Yehuda did one too but I can&#x27;t remember where now). Yehuda pointed out a &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;merb&#x2F;browse_thread&#x2F;thread&#x2F;2536bff7d9195b83&quot;&gt;(heated) discussion that happened recently&lt;&#x2F;a&gt; on keeping Merb syntax as Rails-friendly as possible. I have no objection against a different syntax really, especially since Merb looks pretty well-documented in the source itself - would be nice if someone could point out an up-to-date Merb tutorial though.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, that&#x27;s it from me - as always, if anyone who reads my blog &lt;a href=&quot;http:&#x2F;&#x2F;www.facebook.com&#x2F;profile.php?id=500115784&quot;&gt;recognizes me&lt;&#x2F;a&gt; at RailsConf, do say hi (&lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;railsconf&quot;&gt;#railsconf&lt;&#x2F;a&gt; works too).&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>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>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>Rails and penis enhancements</title>
    <published>2008-01-25T13:34:26+00:00</published>
    <updated>2008-01-25T13:34:26+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/25/rails-and-penis-enhancements/"/>
    <id>https://chuyeow.wtf/2008/01/25/rails-and-penis-enhancements/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/25/rails-and-penis-enhancements/">&lt;p&gt;Funniest bug report I&#x27;ve seen on the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;&quot;&gt;Rails issue tracker&lt;&#x2F;a&gt;: &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10919&quot;&gt;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10919&lt;&#x2F;a&gt;. Be sure to read the comments, and the resolution:&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;I appreciate that penis enhancements are the norm for most of the commenters here, but their use is definitely not widespread enough to justify fixing this.&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&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>Seen in the Rails source - Orcl nds shrt indx nms</title>
    <published>2008-01-18T18:35:41+00:00</published>
    <updated>2008-01-18T18:35:41+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2008/01/18/seen-in-the-rails-source-orcl-nds-shrt-indx-nms/"/>
    <id>https://chuyeow.wtf/2008/01/18/seen-in-the-rails-source-orcl-nds-shrt-indx-nms/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2008/01/18/seen-in-the-rails-source-orcl-nds-shrt-indx-nms/">&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;oracle_short_indexes.png&quot; alt=&quot;Oracle needs short indexes&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;Hah.&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>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>Generating migrations gets easier - Rails 2.0 a feature a day #6</title>
    <published>2007-12-24T16:58:07+00:00</published>
    <updated>2007-12-24T16:58:07+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/"/>
    <id>https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/24/generating-migrations-gets-easier-rails-20-a-feature-a-day-6/">&lt;p&gt;You may not have noticed this yet, but Rails 2.0 has a new convenient syntax for generating ActiveRecord migrations. Go ahead, run the migration generator with &lt;code&gt;script&#x2F;generate migration&lt;&#x2F;code&gt;. I&#x27;ll wait.&lt;&#x2F;p&gt;
&lt;p&gt;Yup, you can now specify the columns you want to add in your migration by passing attribute&#x2F;type pairs to the migration generator. Ergo,&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;script&#x2F;generate migration AddMoreToAnime episodes:integer licensed:boolean&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will generate a migration like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class AddMoreToAnime &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :animes, :episodes, :integer
    add_column :animes, :licensed, :boolean
  end
&lt;p&gt;def self.down
remove_column :animes, :licensed
remove_column :animes, :episodes
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This ties in pretty nicely with the syntax for the model generator (&lt;code&gt;script&#x2F;generate model&lt;&#x2F;code&gt;), which also accepts attribute pairs. Tiny change but &quot;it&#x27;s all about consistency&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;For the geeks among you, check out the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7422&quot;&gt;related changeset&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9166&quot;&gt;ticket&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, Pratik Naik&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;Pratik Naik&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;recommendation&#x2F;new&#x2F;person&#x2F;5424-pratik-naik&quot;&gt;WorkingWithRails profile&lt;&#x2F;a&gt;), probably better known as lifofifo or just lifo, is an active Rails contributor and can be found on &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rails-contrib&quot;&gt;#rails-contrib&lt;&#x2F;a&gt; and &lt;a href=&quot;irc:&#x2F;&#x2F;irc.freenode.net&#x2F;rubyonrails&quot;&gt;#rubyonrails&lt;&#x2F;a&gt; nearly 24&#x2F;7. Almost everyone who&#x27;s used Rails has used code that lifo has written. Oh, and lifo also &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2007&#x2F;11&#x2F;1&#x2F;hackfest-winner-interview-pratik-naik&quot;&gt;won one of the monthly Rails Hackfests&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;He also keeps a &lt;a href=&quot;http:&#x2F;&#x2F;m.onkey.org&#x2F;&quot;&gt;pretty good blog&lt;&#x2F;a&gt; where he posts mostly on Rails hacking and tips.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 2 a feature a day - update</title>
    <published>2007-12-23T12:14:51+00:00</published>
    <updated>2007-12-23T12:14:51+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/23/rails-2-a-feature-a-day-update/"/>
    <id>https://chuyeow.wtf/2007/12/23/rails-2-a-feature-a-day-update/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/23/rails-2-a-feature-a-day-update/">&lt;p&gt;In case anyone is wondering about the pause in &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.0 - a feature a day&lt;&#x2F;a&gt; posts, yes, I know, I&#x27;ve not been writing any posts for a week or so. I&#x27;ll be posting more actively again from tomorrow - just taking a short break due to general lethargy these few days. And &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;search?q=chuyeow&amp;changeset=on&amp;ticket=on&quot;&gt;submitting patches&lt;&#x2F;a&gt; &amp;gt; blogging.&lt;&#x2F;p&gt;
&lt;p&gt;On a somewhat related note, I&#x27;ll be posting weekly updates of edge Rails changes in a tie-up with a particular Rails podcast from the beginning of next year - not gonna say which one!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 2.0.2 released, so what&#x27;s new?</title>
    <published>2007-12-17T11:09:13+00:00</published>
    <updated>2007-12-17T11:09:13+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/17/rails-202-released-so-whats-new/"/>
    <id>https://chuyeow.wtf/2007/12/17/rails-202-released-so-whats-new/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/17/rails-202-released-so-whats-new/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8430&quot;&gt;Rails 2.0.2 was tagged not too long ago&lt;&#x2F;a&gt; and will hit the gem servers soon I expect. Being a minor point release there aren&#x27;t many changes, but here&#x27;re the ones I feel are worth mentioning:&lt;&#x2F;p&gt;
&lt;h3&gt;ActionPack changes&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Configurable asset hosts&lt;&#x2F;strong&gt;: You can now pass a proc to &lt;code&gt;ActionController::Base.asset_host&lt;&#x2F;code&gt;. This allows you to get by the hard-coded assumption that you have 4 asset hosts numbered 0-3 when using the &#x27;%d&#x27; wildcard (introduced in Rails 2.0.1).&lt;&#x2F;p&gt;
&lt;p&gt;I &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10521&quot;&gt;contributed this patch&lt;&#x2F;a&gt; so I&#x27;m gonna be lazy and copy and paste most of the documentation I wrote for patch.&lt;&#x2F;p&gt;
&lt;p&gt;The example proc below generates http:&#x2F;&#x2F;assets1.example.com and http:&#x2F;&#x2F;assets2.example.com randomly.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActionController::Base.asset_host = Proc.new { |source| &quot;http:&#x2F;&#x2F;assets#{rand(2) + 1}.example.com&quot; }
image_tag(&quot;rails.png&quot;)
  =&amp;gt; &amp;lt;img src=&quot;http:&#x2F;&#x2F;assets2.example.com&#x2F;images&#x2F;rails.png&quot; alt=&quot;Rails&quot; &#x2F;&amp;gt;
stylesheet_include_tag(&quot;application&quot;)
  =&amp;gt; &amp;lt;link href=&quot;http:&#x2F;&#x2F;assets1.example.com&#x2F;stylesheets&#x2F;application.css&quot; media=&quot;screen&quot; rel=&quot;stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The proc also takes a single &lt;code&gt;source&lt;&#x2F;code&gt; parameter which is the path of the source asset. This can be used to generate a particular asset host depending on the asset path. This is useful if you have, say, images hosted elsewhere, or you want an SEO-friendly URL for your images:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;ActionController::Base.asset_host = Proc.new { |source|
  if source.starts_with?(&#x27;&#x2F;images&#x27;)
    &quot;http:&#x2F;&#x2F;images.example.com&quot;
  else
    &quot;http:&#x2F;&#x2F;assets.example.com&quot;
  end
}
image_tag(&quot;rails.png&quot;)
  =&amp;gt; &amp;lt;img src=&quot;http:&#x2F;&#x2F;images.example.com&#x2F;images&#x2F;rails.png&quot; alt=&quot;Rails&quot; &#x2F;&amp;gt;
stylesheet_include_tag(&quot;application&quot;)
  =&amp;gt; &amp;lt;link href=&quot;http:&#x2F;&#x2F;assets.example.com&#x2F;stylesheets&#x2F;application.css&quot; media=&quot;screen&quot; rel=&quot;stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Asset cache directories are automatically created&lt;&#x2F;strong&gt;: In Rails 2.0.1, if you tried to cache your assets (javascripts and stylesheets) in a subdirectory (example below), you either need to check it into your source control or have your deployment tool (Capistrano, etc.) create it for you. &lt;a href=&quot;http:&#x2F;&#x2F;joshpeek.com&#x2F;&quot;&gt;Josh Peek&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;10337&quot;&gt;contributed a patch&lt;&#x2F;a&gt; that created the subdirectory instead so you can do something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;javascript_include_tag(:all, :cache =&gt; &quot;cache&#x2F;money&quot;)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and not have to bother about creating the &#x27;cache&#x27; subdirectory.&lt;&#x2F;p&gt;
&lt;h3&gt;Railties changes&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Default database is now SQLite3&lt;&#x2F;strong&gt;: The default database is now SQLite3 instead of MySQL. Running &#x27;rails takeover_the_world_app&#x27; will now come with a database.yml that&#x27;s setup for SQLite3. To get the old behavior (where it&#x27;s preconfigured for MySQL), run &lt;code&gt;rails -d mysql takeover_the_world_app&lt;&#x2F;code&gt; instead. This is mostly to make this &quot;just work&quot; on Mac OS X Leopard, where SQLite3 is already installed with the OS.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Template loading is faster&lt;&#x2F;strong&gt;: DHH has turned on &lt;code&gt;ActionView::Base.cache_template_loading&lt;&#x2F;code&gt; by default in the &lt;code&gt;production.rb&lt;&#x2F;code&gt; environment config file that basically means that Rails no longer does file system stat calls when loading templates. The downside is that you have to restart your Rails application to see templates changes in production mode, but it&#x27;s not really that big an issue since no one should be editing templates anyway &#x27;live&#x27; in a production application.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;New rake tasks for migrations&lt;&#x2F;strong&gt;: &lt;code&gt;rake db:migrate:redo&lt;&#x2F;code&gt; to undo your last migration and re-run it - very useful when developing migrations (when you screw up, that is). &lt;code&gt;rake db:migrate:reset&lt;&#x2F;code&gt; drops the database, re-creates it, and then runs all migrations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;rake task for generating secret keys&lt;&#x2F;strong&gt;: &lt;code&gt;rake secret&lt;&#x2F;code&gt; to generate a secure key that you can use for cookie sessions. This is useful for updating Rails applications from 1.x to 2.x, which uses cookie-based sessions by default and requires a secret key.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;config.action_controller.session = {
  :session_key =&amp;gt; &#x27;_your_app_session&#x27;,
  :secret      =&amp;gt; &#x27;some super long string that you can generate with the rake secret task&#x27;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Personally I just use super long quotes from Family Guy.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s it! For the curious, expect Ruby 1.9 compatibility, improved caching, and big ActionPack and rendering refactoring changes in Rails 2.1.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Sensible GROUP BYs in ActiveRecord::Calculations - Rails 2.0 a feature a day #5</title>
    <published>2007-12-16T15:16:12+00:00</published>
    <updated>2007-12-16T15:16:12+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/16/sensible-group-bys-in-activerecordcalculations/"/>
    <id>https://chuyeow.wtf/2007/12/16/sensible-group-bys-in-activerecordcalculations/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/16/sensible-group-bys-in-activerecordcalculations/">&lt;p&gt;Doing GROUP BYs in ActiveRecord has always been tricky. There&#x27;s a lot of &quot;magic&quot; in ActiveRecord and room for untested edge cases. Thankfully, Rails also has a squadron of eagle-eyed contributors who are on hand to fix unforeseen errors.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if you wanted to do this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Click &amp;lt; ActiveRecord::Base
  belongs_to :site  # site_id foreign key is a String, e.g. &#x27;www.rubyonrails.org&#x27;
end
&lt;h1 id=&quot;now-try-counting-the-number-of-clicks-grouped-by-site&quot;&gt;Now, try counting the number of clicks, grouped by site.&lt;&#x2F;h1&gt;
&lt;p&gt;Click.count(:all, :group =&amp;gt; :site)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;nil-1-nil-3&quot;&gt;=&amp;gt; [[nil, 1], [nil, 3]]&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a surprisingly common thing to do especially when you are producing reports or statistics of any kind and unfortunately decided to go with a non-(auto)numeric foreign key. As you may have noticed, the sites were returned as &lt;code&gt;nil&lt;&#x2F;code&gt; which is totally unhelpful. Thankfully, this has been &lt;a href=&quot;&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6919&gt;fixed in Rails 2.0:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Click.count(:all, :group =&gt; :site)
# =&gt; [[nil, 1], [&#x27;www.site, 3]]&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3&gt;GROUP BY and :foreign_key don&#x27;t mix&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;This change is NOT in Rails 2.0.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you wanted to do GROUP BYs in your ActiveRecord models (via the &lt;code&gt;:group&lt;&#x2F;code&gt; option), you had to take note of one particular gotcha. For example, with an ActiveRecord model like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Anime &amp;lt; ActiveRecord::Base
  belongs_to :japanese_studio, :class_name =&amp;gt; &#x27;Studio&#x27;, :foreign_key =&amp;gt; &#x27;studio_id&#x27;
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that we specified the &lt;code&gt;:foreign_key&lt;&#x2F;code&gt; option since it can&#x27;t be inferred from the association name of &#x27;japanese_studio&#x27;. If we wanted to &lt;code&gt;count&lt;&#x2F;code&gt;ing the number of anime grouped by studio though, we&#x27;re in big trouble:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Anime.count(:all, :group =&gt; :japanese_studio)
# ActiveRecord fails and mumbles about an unknown &quot;japanese_studio_id&quot; key.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Basically what happened is Rails did not use the specified foreign key column of &#x27;studio_id&#x27;, inferring it instead from the association name of &#x27;japanese_studio&#x27;. This is not yet fixed but there&#x27;s already a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8117&quot;&gt;patch&lt;&#x2F;a&gt; ready for it at the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;&quot;&gt;Rails issue tracker&lt;&#x2F;a&gt;. In fact, I&#x27;m gonna &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2007&#x2F;9&#x2F;15&#x2F;how-to-get-a-patch-into-rails&quot;&gt;verify it&lt;&#x2F;a&gt; right after posting this.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, Kamal Fariz&lt;&#x2F;h3&gt;
&lt;p&gt;I thought it was time to cover Rails 2.0 contributions by someone closer to home (&quot;home&quot; being my home, &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Singapore&quot;&gt;Singapore&lt;&#x2F;a&gt;) so I singled out &lt;a href=&quot;http:&#x2F;&#x2F;blog.bitfluent.com&#x2F;&quot;&gt;Kamal Fariz&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;4207-kamal-fariz&quot;&gt;WorkingWithRails profile&lt;&#x2F;a&gt;), a Rails developer working in Malaysia for a &lt;a href=&quot;http:&#x2F;&#x2F;blog.ror.com.my&#x2F;&quot;&gt;Rails shop&lt;&#x2F;a&gt;. Kamal&#x27;s also a former &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;hackfest&quot;&gt;Rails Hackfest&lt;&#x2F;a&gt; winner (read the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2007&#x2F;7&#x2F;25&#x2F;hackfest-winner-interview-kamal-fariz&quot;&gt;post-Rails Hackfest interview&lt;&#x2F;a&gt;). Kamal is also an active member of the &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;malaysia-rb?hl=en&quot;&gt;Malaysia Ruby Brigade&lt;&#x2F;a&gt; (I guess it&#x27;s not called a &quot;Ruby User Group&quot; since &quot;RUG&quot; sounds rather unglamorous).&lt;&#x2F;p&gt;
&lt;p&gt;Wow look at the number of parentheses I used in the last paragraph. For no reason whatsoever here&#x27;s a lolcats picture:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;br style=&quot;clear: both;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>ActiveRecord::Base.with_scope { :only =&gt; &#x27;in your model&#x27; } - Rails 2.0 a feature a day #4</title>
    <published>2007-12-16T13:44:34+00:00</published>
    <updated>2007-12-16T13:44:34+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/16/activerecordbasewith_scope-only-in-your-model-rails-20-a-feature-a-day-4/"/>
    <id>https://chuyeow.wtf/2007/12/16/activerecordbasewith_scope-only-in-your-model-rails-20-a-feature-a-day-4/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/16/activerecordbasewith_scope-only-in-your-model-rails-20-a-feature-a-day-4/">&lt;p&gt;Today&#x27;s (un)feature covers the oft-abused and misunderstood &lt;code&gt;with_scope&lt;&#x2F;code&gt; method. The excellent err.the_blog had a post on &lt;a href=&quot;http:&#x2F;&#x2F;errtheblog.com&#x2F;posts&#x2F;39-withscope-with-scope&quot;&gt;how you should be using &lt;code&gt;with_scope&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (yes, only use it in your ActiveRecord models, &lt;em&gt;not&lt;&#x2F;em&gt; in your controllers or filters). Yes that blog post may have been written a long time back but it&#x27;s still applicable to Rails 2.0.&lt;&#x2F;p&gt;
&lt;p&gt;With Rails 2.0, the &lt;code&gt;with_scope&lt;&#x2F;code&gt; method is now &lt;code&gt;protected&lt;&#x2F;code&gt;, meaning that you can no longer use it in your controllers (unless you use the &lt;code&gt;#send(:with_scope)&lt;&#x2F;code&gt;, or &lt;code&gt;#send!(:with_scope)&lt;&#x2F;code&gt; in Ruby 1.9). I&#x27;m not even going to show you how you could use it in your controllers since you really shouldn&#x27;t (unless you know what you are doing).&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what &lt;code&gt;with_scope&lt;&#x2F;code&gt; allows you to do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class SiteOwner &amp;lt; ActiveRecord::Base
&lt;h1 id=&quot;returns-list-of-distinct-active-sites&quot;&gt;Returns list of distinct active sites.&lt;&#x2F;h1&gt;
&lt;p&gt;def active_sites(*args)
with_scope :find =&amp;gt; { :select =&amp;gt; &#x27;DISTINCT(site)&#x27;, :conditions =&amp;gt; { :active =&amp;gt; true } } do
find(*args).collect(&amp;amp;:site)
end
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And even better example, stolen from the &lt;a href=&quot;http:&#x2F;&#x2F;errtheblog.com&#x2F;posts&#x2F;39-withscope-with-scope&quot;&gt;err.the_blog post&lt;&#x2F;a&gt; mentioned above, is re-using scopes:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Movie &amp;lt; ActiveRecord::Base
  def self.find_playing(*args)
    with_playing do
      find(*args)
    end
  end
&lt;p&gt;def self.find_playing_by_id
with_playing do
find_by_id(*args)
end
end&lt;&#x2F;p&gt;
&lt;p&gt;def self.with_playing
with_scope :find =&amp;gt; { :conditions =&amp;gt; [ state = ? AND visible = ?, NOW_PLAYING, true ] } do
yield
end
end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I tend to use that a lot combined with &lt;code&gt;method_missing&lt;&#x2F;code&gt; magic (also from the &lt;a href=&quot;http:&#x2F;&#x2F;errtheblog.com&#x2F;posts&#x2F;39-withscope-with-scope&quot;&gt;err.the_blog post&lt;&#x2F;a&gt;) to allow me to do things like &lt;code&gt;Movie.find_playing_by_name&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def self.method_missing(method, *args, &amp;amp;block)
  if method.to_s =~ &#x2F;^find_(all_)?playing_by&#x2F;
    with_playing do
      super(method.to_s.sub(&#x27;playing_&#x27;, &#x27;&#x27;), *args, &amp;amp;block)
    end
  else
    super(method, *args, &amp;amp;block)
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you prefer to get these for free, check out the the &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;scope-out-rails&#x2F;&quot;&gt;Rails scope-out plugin&lt;&#x2F;a&gt; implements many of the ideas in the err.the_blog post.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, Josh Peek&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;joshpeek.com&#x2F;&quot;&gt;Josh Peek&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;person&#x2F;6183-josh-peek&quot;&gt;WorkingWithRails profile&lt;&#x2F;a&gt;) was the man behind the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8524&quot;&gt;&quot;protection&quot; of with_scope&lt;&#x2F;a&gt;. This is not Josh&#x27;s greatest contribution to Rails, of course - Josh has been a very productive and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;report&#x2F;37?DATE=2007-01-01&quot;&gt;active&lt;&#x2F;a&gt; Rails contributor since the very beginning. A winner of one of the monthly &lt;a href=&quot;http:&#x2F;&#x2F;www.workingwithrails.com&#x2F;hackfest&quot;&gt;Rails Hackfest&lt;&#x2F;a&gt;, you can read up on the ever-elusive (I say &quot;elusive&quot; because he doesn&#x27;t have a blog - it&#x27;s just patch after patch after patch) Josh Peek in this &lt;a href=&quot;http:&#x2F;&#x2F;weblog.workingwithrails.com&#x2F;2007&#x2F;8&#x2F;6&#x2F;hackfest-winner-interview-josh-peek&quot;&gt;post-Rails Hackfest interview&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Josh is also the man behind the deprecation and &quot;plugin-izing&quot; of dynamic scaffolding and pagination (yes, those are gone from Rails 2.0) among a great number of other patches and test coverage improvements. Right now, Josh appears to be &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.ca&#x2F;group&#x2F;rubyonrails-core&#x2F;browse_thread&#x2F;thread&#x2F;13bba76b624c276e&quot;&gt;working on refactoring ActionView&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;Outro&lt;&#x2F;h3&gt;
&lt;p&gt;Apologies for the late-on-arrival &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.0 a feature a day&lt;&#x2F;a&gt; posts, but such is life. &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;16&#x2F;sensible-group-bys-in-activerecordcalculations&#x2F;&quot;&gt;Feature #5&lt;&#x2F;a&gt; follows immediately after :)&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Concatenate your stylesheets and JavaScripts in 3 seconds - Rails 2.0 a feature a day #3</title>
    <published>2007-12-12T23:25:39+00:00</published>
    <updated>2007-12-12T23:25:39+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/"/>
    <id>https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/12/concatenate-your-stylesheets-and-javascripts-in-3-seconds-rails-20-a-feature-a-day-3/">&lt;p&gt;I don&#x27;t think I need to explain how &lt;a href=&quot;http:&#x2F;&#x2F;developer.yahoo.com&#x2F;performance&#x2F;rules.html#num_http&quot;&gt;concatenating your 5 stylesheets and 12 JavaScript files into single files&lt;&#x2F;a&gt; each makes your webpages load faster. Unless you&#x27;re using multiple asset hosts (Rails 2 allows for &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6161&quot;&gt;multiple asset hosts&lt;&#x2F;a&gt;), then it becomes tricky to say for sure which method is better, but I digress.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;re a bunch of really useful plugins that help you bundle your JS and CSS files, most of them offering minifying&#x2F;packing of JS and stripping of comments and whitespace in CSS as well. I was a big fan (still love it) of &lt;a href=&quot;http:&#x2F;&#x2F;synthesis.sbecker.net&#x2F;pages&#x2F;asset_packager&quot;&gt;Asset Packager&lt;&#x2F;a&gt;, but newer plugins like &lt;a href=&quot;http:&#x2F;&#x2F;blog.jcoglan.com&#x2F;packr&#x2F;&quot;&gt;PackR&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;bundle-fu&#x2F;&quot;&gt;Bundle-fu&lt;&#x2F;a&gt; work great too.&lt;&#x2F;p&gt;
&lt;p&gt;With Rails 2.0 though, unless you want the minifying&#x2F;packing&#x2F;comment-stripping features, you can do away with installing a packager plugin. Remember your trusty &lt;code&gt;javascript_include_tag&lt;&#x2F;code&gt; and &lt;code&gt;stylesheet_link_tag&lt;&#x2F;code&gt;? They now accept a &lt;code&gt;:cache&lt;&#x2F;code&gt; option:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;# :cache =&amp;gt; true creates a cached javascript named all.js.
&amp;lt;%= javascript_include_tag :all, :cache =&amp;gt; true %&amp;gt;
# This becomes:
# &amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;all.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;h1 id=&quot;you-can-name-your-javascript-too-by-passing-a-name-instead-of-true&quot;&gt;You can name your javascript too, by passing a name instead of true.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= javascript_include_tag &#x27;jquery&#x27;, &#x27;swfobject&#x27;, &#x27;application&#x27;, :cache =&amp;gt; &#x27;base&#x27; %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;script-type-text-javascript-src-javascripts-base-js-script&quot;&gt;&amp;lt;script type=&quot;text&#x2F;javascript&quot; src=&quot;&#x2F;javascripts&#x2F;base.js&quot;&amp;gt;&amp;lt;&#x2F;script&amp;gt;&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;same-deal-for-stylesheets&quot;&gt;Same deal for stylesheets...&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;cache-true-creates-a-stylesheet-named-all-css&quot;&gt;:cache =&amp;gt; true creates a stylesheet named all.css.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= stylesheet_link_tag :all, :cache =&amp;gt; true %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes-1&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;link-href-stylesheets-all-css-media-screen-rel-stylesheet-type-text-css&quot;&gt;&amp;lt;link href=&quot;&#x2F;stylesheets&#x2F;all.css&quot;  media=&quot;screen&quot; rel=&quot;Stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;you-can-name-your-stylesheet-like-for-javascript-include-tag&quot;&gt;You can name your stylesheet like for javascript_include_tag.&lt;&#x2F;h1&gt;
&lt;p&gt;&amp;lt;%= stylesheet_link_tag &#x27;yui&#x2F;reset-fonts-grids&#x27;, &#x27;application&#x27;, :cache =&amp;gt; &#x27;styles&#x27; %&amp;gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;this-becomes-2&quot;&gt;This becomes:&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;link-href-stylesheets-styles-css-media-screen-rel-stylesheet-type-text-css&quot;&gt;&amp;lt;link href=&quot;&#x2F;stylesheets&#x2F;styles.css&quot;  media=&quot;screen&quot; rel=&quot;Stylesheet&quot; type=&quot;text&#x2F;css&quot; &#x2F;&amp;gt;&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, this only takes place if caching is turned on (&lt;code&gt;ActionController::Base.perform_caching&lt;&#x2F;code&gt;), which is on by default in the production environment and off in the development environment.&lt;&#x2F;p&gt;
&lt;p&gt;For those who want to look at some code, check out &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6164&quot;&gt;the changeset&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;About the contributor, DHH&lt;&#x2F;h3&gt;
&lt;p&gt;Well, &lt;a href=&quot;http:&#x2F;&#x2F;loudthinking.com&#x2F;&quot;&gt;DHH&lt;&#x2F;a&gt; hardly needs any mention. David has_one &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;David_Heinemeier_Hansson&quot;&gt;Wikipedia entry&lt;&#x2F;a&gt;. Nice little touch on this new feature though, I love the convenience.&lt;&#x2F;p&gt;
&lt;p&gt;I promise, like &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;I&#x27;d said before&lt;&#x2F;a&gt;, to cover contributions by someone less &quot;mainstream&quot; in the next &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 &quot;feature a day&quot;&lt;&#x2F;a&gt; blog post.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 2.0 - a feature a day</title>
    <published>2007-12-09T23:50:41+00:00</published>
    <updated>2007-12-09T23:50:41+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/09/rails-20-a-feature-a-day/"/>
    <id>https://chuyeow.wtf/2007/12/09/rails-20-a-feature-a-day/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/09/rails-20-a-feature-a-day/">&lt;p&gt;Now that Rails 2.0 has been baked to near-perfection, I&#x27;m sure all you Rubyists with Rails applications are considering updating or have already updated your applications to be Rails 2.0-compatible. And you&#x27;ve probably already pored through the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2007&#x2F;12&#x2F;7&#x2F;rails-2-0-it-s-done&quot;&gt;massive list of new features and changes in Rails 2.0&lt;&#x2F;a&gt; or seen it on &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2007&#x2F;12&#x2F;7&#x2F;rails-2-0-final-released-summary-of-features&#x2F;&quot;&gt;Ryan Daigle&#x27;s Scraps&lt;&#x2F;a&gt;. Ryan also wrote a &lt;a href=&quot;http:&#x2F;&#x2F;peepcode.com&#x2F;products&#x2F;rails2-pdf&quot;&gt;Rails2 mini eBook&lt;&#x2F;a&gt; that&#x27;s been getting &lt;a href=&quot;http:&#x2F;&#x2F;beneathzooppa.blogspot.com&#x2F;2007&#x2F;10&#x2F;peepcode-rails-20-mini-book.html&quot;&gt;good&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;articles&#x2F;2007&#x2F;12&#x2F;7&#x2F;rails-2-0-final-released-summary-of-features&#x2F;#comments&quot;&gt;reviews&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been keeping track of the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;timeline&quot;&gt;Rails Trac timeline&lt;&#x2F;a&gt; myself since &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9677&quot;&gt;my 1st committed Rails patch&lt;&#x2F;a&gt; mostly to keep track of Rails development (&lt;a href=&quot;http:&#x2F;&#x2F;bezurk.com&#x2F;&quot;&gt;we&lt;&#x2F;a&gt; run several apps on edge) and to monitor any comments on my submitted patches. Turns out keeping an eye on the timeline and the &lt;a href=&quot;http:&#x2F;&#x2F;groups.google.com&#x2F;group&#x2F;rubyonrails-core&quot;&gt;rubyonrails-core mailing list&lt;&#x2F;a&gt; gives you a pretty decent &quot;on the ground&quot; view of new features and changes to the Rails trunk.&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;m gonna try something and see if helps anyone: I&#x27;ll be running a near-daily series of blog posts about new Rails features or changes. I&#x27;ll try not to repeat anything that&#x27;s already &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;&quot;&gt;been&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2007&#x2F;12&#x2F;7&#x2F;rails-2-0-it-s-done&quot;&gt;mentioned&lt;&#x2F;a&gt;, and instead focus more on lesser-known changes. I think it&#x27;s also a great opportunity to raise the profile of the core committers and contributors to the Rails community so look out for an &quot;About the contributor&quot; section in each post.&lt;&#x2F;p&gt;
&lt;p&gt;Hop on over to the 1st post - &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;12&#x2F;09&#x2F;timeadvance-now-uses-weeks-hours-minutes-seconds-options-rails-20-a-feature-a-day-1&#x2F;&quot;&gt;Time#advance now uses :weeks, :hours, :minutes, :seconds options&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 2.0 released</title>
    <published>2007-12-08T00:02:09+00:00</published>
    <updated>2007-12-08T00:02:09+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/08/rails-20-released/"/>
    <id>https://chuyeow.wtf/2007/12/08/rails-20-released/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/08/rails-20-released/">&lt;p&gt;Just go to the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.org&#x2F;2007&#x2F;12&#x2F;7&#x2F;rails-2-0-it-s-done&quot;&gt;release announcement and major features blog post by DHH&lt;&#x2F;a&gt; already!&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re having trouble installing the Rails 2.0.1 gem, do a &lt;code&gt;gem install rails -y --source http:&#x2F;&#x2F;gems.rubyonrails.org&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now that the obligatory link to the Rails 2.0 release announcement is done, I&#x27;d like to urge anyone with any interest in improving Rails or seeing new features or fixes in Rails to try and contribute to Rails. I&#x27;m sure everyone of us Rails users have had &quot;what if Rails could do this&quot; or &quot;why is Rails doing this, that&#x27;s just wrong&quot; moments. Well, roll up your sleeves and help by contributing instead of complaining about how &lt;a href=&quot;http:&#x2F;&#x2F;www.koziarski.net&#x2F;archives&#x2F;2007&#x2F;12&#x2F;1&#x2F;they&quot;&gt;&quot;they&quot;&lt;&#x2F;a&gt; won&#x27;t&#x2F;haven&#x27;t&#x2F;are too stupid to fix it..&lt;&#x2F;p&gt;
&lt;p&gt;A good starting point is to read the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;wiki&#x2F;&quot;&gt;Rails Trac wiki&lt;&#x2F;a&gt;, and after that be sure to check out John Susser&#x27;s excellent &lt;a href=&quot;http:&#x2F;&#x2F;hasmanythrough.com&#x2F;layingtracks&#x2F;&quot;&gt;guide to contributing to Rails&lt;&#x2F;a&gt; (read the &lt;a href=&quot;http:&#x2F;&#x2F;hasmanythrough.com&#x2F;layingtracks&#x2F;LayingTracks.pdf&quot;&gt;presentation slides&lt;&#x2F;a&gt;, it won&#x27;t take long). You should have enough information to start. I recommend just opening the &lt;code&gt;base.rb&lt;&#x2F;code&gt; classes for ActiveRecord, ActionController and peeking around the ActiveSupport classes just to get a feel of things. After that crack open the relevant test for your issue and write your test-driven patch!&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s really easy, since Rails is written purely in Ruby - if I can do it I&#x27;m sure you can too :) Your contribution doesn&#x27;t even have to be a bona fide patch file with tests, documentation and bits of Ruby code - if you notice a bug and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;newticket&quot;&gt;report it&lt;&#x2F;a&gt; not knowing how to fix it, that&#x27;s good enough! Or even something as trivial as a new style (CSS and layout) for the Rails error pages (there isn&#x27;t such a patch yet but I&#x27;d love to see prettier default exception pages instead of the current rather plain-looking ones).&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, that&#x27;s enough of the sermon from me - enjoy your Rails 2.0! Congrats to the &lt;a href=&quot;http:&#x2F;&#x2F;rubyonrails.org&#x2F;core&quot;&gt;Rails Core team&lt;&#x2F;a&gt; and contributors on another solid release!&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Rails 2.0 - it&#x27;s landed</title>
    <published>2007-12-07T14:14:59+00:00</published>
    <updated>2007-12-07T14:14:59+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/12/07/rails-20-its-landed/"/>
    <id>https://chuyeow.wtf/2007/12/07/rails-20-its-landed/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/12/07/rails-20-its-landed/">&lt;p&gt;&lt;ins&gt;Update: Looks like it&#x27;s going to be released as Rails 2.0.1 instead due to a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8329&quot;&gt;bugfix&lt;&#x2F;a&gt; post-2.0 tagging.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Just a quick one - seems like Rails 2.0 has been &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8328&quot;&gt;tagged for release&lt;&#x2F;a&gt;. &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;milestone&#x2F;2.0&quot;&gt;Rails 2.0 milestone&lt;&#x2F;a&gt; has just been completed.&lt;&#x2F;p&gt;
&lt;p&gt;Expect a post on &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.com&#x2F;&quot;&gt;weblog.rubyonrails.com&lt;&#x2F;a&gt; soon.&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>Konata Izumi in Edge Rails</title>
    <published>2007-10-15T16:25:50+00:00</published>
    <updated>2007-10-15T16:25:50+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/10/15/konata-izumi-in-edge-rails/"/>
    <id>https://chuyeow.wtf/2007/10/15/konata-izumi-in-edge-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/10/15/konata-izumi-in-edge-rails/">&lt;p&gt;You wouldn&#x27;t think that &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;2007&#x2F;05&#x2F;11&#x2F;lucky-star-konata-ism&#x2F;&quot;&gt;Konata Izumi&lt;&#x2F;a&gt; (a character from the anime, &lt;a href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lucky_Star_(manga)&quot;&gt;Lucky Star&lt;&#x2F;a&gt;) and Ruby on Rails (a web MVC framework) would somehow be associated, but they are!&lt;&#x2F;p&gt;
&lt;p&gt;I took the opportunity to fill in the missing &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activerecord&#x2F;lib&#x2F;active_record&#x2F;serializers&#x2F;json_serializer.rb?rev=7905&quot;&gt;&lt;code&gt;ActiveRecord::Base#to_json&lt;&#x2F;code&gt; documentation&lt;&#x2F;a&gt; with examples using Konata Izumi and it got committed unchanged in &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7905&quot;&gt;revision 7905&lt;&#x2F;a&gt;. Cute. I hope no one changes them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;ins&gt;Update: Managed to get &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;8010&quot;&gt;more Konata Izumi documentation&lt;&#x2F;a&gt; into Rails ;)&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New on edge Rails: JSON serialization of ActiveRecord objects reaches maturity</title>
    <published>2007-10-10T00:13:02+00:00</published>
    <updated>2007-10-10T00:13:02+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/10/10/new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity/"/>
    <id>https://chuyeow.wtf/2007/10/10/new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/10/10/new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity/">&lt;p&gt;The last time I &lt;a href=&quot;&#x2F;2007&#x2F;09&#x2F;24&#x2F;new-in-edge-rails-serialize-activerecord-objects-to-json-with-activerecordto_json&#x2F;&quot;&gt;wrote about &lt;code&gt;ActiveRecord#to_json&lt;&#x2F;code&gt; on edge Rails&lt;&#x2F;a&gt;, it was missing some key functionality. For one, you couldn&#x27;t include any associations. Another thing was you couldn&#x27;t do something like this in your controller:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;@authors = Author.find(:all)
&lt;p&gt;render :json =&amp;gt; @authors.to_json(:only =&amp;gt; :name)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Oh and did I mention &lt;a href=&quot;&#x2F;2007&#x2F;06&#x2F;20&#x2F;how-to-get-strictly-valid-json-from-rails&#x2F;&quot;&gt;it wasn&#x27;t emitting valid JSON by default&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;In the last few weeks, several patches to the Rails trunk have fixed all these issues (most of these patches are already on the &lt;a href=&quot;http:&#x2F;&#x2F;weblog.rubyonrails.com&#x2F;2007&#x2F;9&#x2F;30&#x2F;rails-2-0-0-preview-release&quot;&gt;Rails 2.0 Preview Release&lt;&#x2F;a&gt;). JSON serialization of ActiveRecord objects is &lt;em&gt;finally&lt;&#x2F;em&gt; on par with XML serialization, and that old &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;Jsonifier plugin&lt;&#x2F;a&gt; I wrote can finally be sent off to the plugin retirement home (though, I am thinking of porting all the JSON patches into Jsonifier to add Rails 2.0-like JSON serialization to Rails 1.2.4, but who knows, I &lt;em&gt;am&lt;&#x2F;em&gt; lazy).&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, back to the new JSON stuff on edge Rails.&lt;&#x2F;p&gt;
&lt;h3&gt;No more invalid JSON from Rails&lt;&#x2F;h3&gt;
&lt;p&gt;Yes it&#x27;s true. No more &lt;a href=&quot;&#x2F;2007&#x2F;06&#x2F;20&#x2F;how-to-get-strictly-valid-json-from-rails&#x2F;&quot;&gt;changing of module attribute to get Rails to produce valid JSON&lt;&#x2F;a&gt;. Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;blog.choonkeat.com&#x2F;&quot;&gt;Choon Keat&lt;&#x2F;a&gt; with his &lt;a href=&quot; http:&#x2F;&#x2F;www.ruby-forum.com&#x2F;topic&#x2F;124797&quot;&gt;detailed SVN history snooping&lt;&#x2F;a&gt;, we finally managed to get a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8762&quot;&gt;patch to fix JSON encoding to quote all hash keys&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7697&quot;&gt;into Rails&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3&gt;:include option can be used to include associations with ActiveRecord::Base#to_json&lt;&#x2F;h3&gt;
&lt;p&gt;At &lt;a href=&quot;&#x2F;2007&#x2F;09&#x2F;24&#x2F;new-in-edge-rails-serialize-activerecord-objects-to-json-with-activerecordto_json&#x2F;#comment-286519&quot;&gt;DHH&#x27;s urging&lt;&#x2F;a&gt;, I submitted a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9677&quot;&gt;patch that added the &lt;code&gt;:include&lt;&#x2F;code&gt; option to &lt;code&gt;ActiveRecord#to_json&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. Of course, it was a sloppy first submission and &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9677#comment:2&quot;&gt;DHH pointed that out&lt;&#x2F;a&gt; - a little bit of DRY love and it was really great to see it &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7663&quot;&gt;get committed&lt;&#x2F;a&gt; (I have a soft spot for JSON serialization from Rails, since I&#x27;d been trying to achieve the same thing with &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&#x2F;&quot;&gt;Jsonifier&lt;&#x2F;a&gt;). &lt;&#x2F;p&gt;
&lt;p&gt;So yes, now you can do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;json = @david.to_json(:include =&gt; :posts)
# or even...
json = @david.to_json(
  :include =&gt; {
    :posts =&gt; {
      :include =&gt; {
        :taggings =&gt; {
          :include =&gt; {
            :tag =&gt; { :only =&gt; :name }
          }
        }
      }
    }
})&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3&gt;Enumerable#to_json and Hash#to_json now accept options&lt;&#x2F;h3&gt;
&lt;p&gt;One problem with Jsonifier that I often get emails about is how the &lt;code&gt;to_json&lt;&#x2F;code&gt; options don&#x27;t work for lists (Enumerables). And why is this important? Well, we often retrieve collections of ActiveRecord objects at a time with &lt;code&gt;AR::B#find&lt;&#x2F;code&gt; so it&#x27;s not too much to ask to be able to do this in your controller actions:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;@authors = Author.find(:all)
&lt;p&gt;render :json =&amp;gt; @authors.to_json(:only =&amp;gt; :name)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But of course you couldn&#x27;t, so I &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9751&quot;&gt;patched away&lt;&#x2F;a&gt; by changing the &lt;code&gt;to_json&lt;&#x2F;code&gt; methods of Enumerable and Hash (and other types as well) to accept an optional &lt;code&gt;options&lt;&#x2F;code&gt; argument. Enumerables will pass on any &lt;code&gt;options&lt;&#x2F;code&gt; it receives to its elements. Hashes will respect :only and :except (as well as passing on the &lt;code&gt;options&lt;&#x2F;code&gt; to its elements).&lt;&#x2F;p&gt;
&lt;h3&gt;Unambiguous (non-US-centric) dates and times&lt;&#x2F;h3&gt;
&lt;p&gt;While Rails 1.2.3 (and 1.2.4) never supported encoding of Dates, Times and DateTimes, edge Rails has been happily supporting Date, Time and DateTime conversions to JSON since &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;6773&quot;&gt;revision 6673&lt;&#x2F;a&gt;. Unfortunately, the date string format is in MM&#x2F;DD&#x2F;YYYY format:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Time.now.to_json
=&gt; &quot;\&quot;09&#x2F;21&#x2F;2007 12:15:02 UTC\&quot;&quot;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Geoff Buesing suggested that Rails should &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9750&quot;&gt;change this&lt;&#x2F;a&gt; to the more unambiguous YYYY&#x2F;MM&#x2F;DD format. Finding the right date format is important not only for readability reasons, it&#x27;s also important that the date string is directly parsable by the many browser JavaScript implementations using the JavaScript &lt;code&gt;new Date(dateString)&lt;&#x2F;code&gt; function. There is no formal spec of how dates should be represented in JSON, but it&#x27;s most convenient that strings representing dates can be directly converted into JavaScript Date objects.&lt;&#x2F;p&gt;
&lt;p&gt;Testing in several browsers and on different platforms, albeit not extensively, we settled on the &lt;code&gt;%Y&#x2F;%m&#x2F;%d %H:%M:%S %z&lt;&#x2F;code&gt; (strftime) format (more details in the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9750&quot;&gt;comments of the Trac ticket&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Now it is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Time.now.to_json
=&gt; &quot;\&quot;2007&#x2F;09&#x2F;21 12:15:02 +0800\&quot;&quot;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Much better.&lt;&#x2F;p&gt;
&lt;h3&gt;What&#x27;s left?&lt;&#x2F;h3&gt;
&lt;p&gt;Documentation, for one thing. ActiveRecord::Base#to_json is still undocumented (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9814&quot;&gt;docfix patch&lt;&#x2F;a&gt;). The &lt;code&gt;to_json&lt;&#x2F;code&gt; methods for Enumerable and Hash need documentation as well (will patch that soon).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ActiveRecord::Base#to_json&lt;&#x2F;code&gt; also doesn&#x27;t deal with binary attributes, which can be easily resolved by Base64-encoding them (patch coming soon, it gets slightly complicated when trying to do a &lt;code&gt;from_json&lt;&#x2F;code&gt;). And of course, optimization improvements are always nice (decoding from JSON especially).&lt;&#x2F;p&gt;
&lt;p&gt;So, if you use JSON at all, please come in and help patch the remaining bits before Rails 2.0 rolls out. If you can&#x27;t (or more realistically, don&#x27;t have the time to) patch Rails yourself, do help out by verifying patches :).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>So apparently I&#x27;m a Rails Hackfest winner...</title>
    <published>2007-10-03T02:19:29+00:00</published>
    <updated>2007-10-03T02:19:29+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/10/03/so-apparently-im-a-rails-hackfest-winner/"/>
    <id>https://chuyeow.wtf/2007/10/03/so-apparently-im-a-rails-hackfest-winner/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/10/03/so-apparently-im-a-rails-hackfest-winner/">&lt;p&gt;Got an email not too long ago from &lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;&quot;&gt;Working With Rails&lt;&#x2F;a&gt; (&lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;person&#x2F;5957-cheah-chu-yeow&quot;&gt;my profile&lt;&#x2F;a&gt;) entitled &quot;WWR September Hackfest Winner - Congrats!&quot;, and almost deleted it thinking it was spam. I read it in the end (after all, how often do you see spam with &quot;Rails&quot; in the subject title), and turns out that &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7663&quot;&gt;my&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7699&quot;&gt;recent&lt;&#x2F;a&gt; &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7697&quot;&gt;patches&lt;&#x2F;a&gt; to Rails pushed me up to 6th position in the &lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;hackfest&#x2F;15-monthly-september-2-7&quot;&gt;September Rails contributors rankings&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;hackfest_sept_2007_thumb.png&quot; alt=&quot;Rails Hackfest September 2007 winners&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 vaguely remember seeing &lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;hackfest&quot;&gt;Rails Hackfest&lt;&#x2F;a&gt; mentioned somewhere but only just realized it&#x27;s a &quot;contest&quot; run monthly. The winners are the top 10 contributors to Rails (contribution being determined by the number of accepted patches, docfixes, and even comments). That&#x27;s really nice of the sponsors and &lt;a href=&quot;http:&#x2F;&#x2F;workingwithrails.com&#x2F;&quot;&gt;Working With Rails&lt;&#x2F;a&gt;, since that wasn&#x27;t really what I&#x27;d expected in return for contributing to an Open Source project (that would be &lt;em&gt;a sense of satisfaction&lt;&#x2F;em&gt;, personally-speaking).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m just really glad that the JSON patches went into Rails before Rails 2.0 and it is satisfying to see my code get into Rails (I&#x27;ll blog about the patches in a separate post). There&#x27;s still &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9751&quot;&gt;some more work&lt;&#x2F;a&gt; needed though - please help to verify and give suggestions or +1s ;).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Edge Rails: helper for creating form labels</title>
    <published>2007-09-25T10:40:55+00:00</published>
    <updated>2007-09-25T10:40:55+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/"/>
    <id>https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/09/25/new-in-edge-rails-helper-for-creating-form-labels/">&lt;p&gt;Edge Rails now comes with a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7541&quot;&gt;helper for creating form labels&lt;&#x2F;a&gt;, so in your views, instead of doing this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_for(:user, @user, :url =&gt; user_path(@user)) do |f| -%&amp;gt;
&lt;strong&gt;&amp;lt;label for=&quot;user_login&quot;&amp;gt;Login&amp;lt;&#x2F;label&amp;gt;&lt;&#x2F;strong&gt;
&amp;lt;%= f.text_field :login %&amp;gt;
&amp;lt;end&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where the &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt; is given a &lt;code&gt;for&lt;&#x2F;code&gt; attribute of &lt;code&gt;user_login&lt;&#x2F;code&gt; (since the convention for form input ids is &lt;code&gt;{MODEL_NAME}_{ATTRIBUTE_NAME}&lt;&#x2F;code&gt;), you can instead now do:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;%= label(:user, :login) %&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Quite a bit neater. Makes it easier to explain to beginners how they should use &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt;s appropriately since the syntax is similar to the other form helpers. Now give your &lt;code&gt;&amp;lt;label&amp;gt;&lt;&#x2F;code&gt;s proper &lt;code&gt;for&lt;&#x2F;code&gt; attributes if you&#x27;re not doing so already.&lt;&#x2F;p&gt;
&lt;p&gt;This makes plugins like this &lt;a href=&quot;http:&#x2F;&#x2F;simple-rails-plugins.googlecode.com&#x2F;svn&#x2F;form-label-helper&#x2F;&quot;&gt;form label helper plugin&lt;&#x2F;a&gt; obsolete.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>New in Edge Rails: Serialize ActiveRecord objects to JSON with ActiveRecord#to_json</title>
    <published>2007-09-24T10:14:12+00:00</published>
    <updated>2007-09-24T10:14:12+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/09/24/new-in-edge-rails-serialize-activerecord-objects-to-json-with-activerecordto_json/"/>
    <id>https://chuyeow.wtf/2007/09/24/new-in-edge-rails-serialize-activerecord-objects-to-json-with-activerecordto_json/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/09/24/new-in-edge-rails-serialize-activerecord-objects-to-json-with-activerecordto_json/">&lt;p&gt;Converting ActiveRecord instances to their JSON representation has always been a topic that has been dear to me. I&#x27;d tried to get &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;8920&quot;&gt;a patch that adds &lt;code&gt;to_json&lt;&#x2F;code&gt; to ActiveRecord&lt;&#x2F;a&gt; into Rails (but the quality of my patch was lacking in a few respects). The &lt;a href=&quot;http:&#x2F;&#x2F;trac.codefront.net&#x2F;jsonifier&quot;&gt;Jsonifier plugin&lt;&#x2F;a&gt; that I wrote tried to address the lack of built-in JSON serialization by adding a &lt;code&gt;ActiveRecord#to_json&lt;&#x2F;code&gt; method that acts much like &lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So it is with mixed feelings when I discovered a couple of days ago when &lt;a href=&quot;http:&#x2F;&#x2F;loudthinking.com&#x2F;&quot;&gt;&lt;acronym title=&quot;David Heinemeier Hansson&quot;&gt;DHH&lt;&#x2F;acronym&gt;&lt;&#x2F;a&gt; committed a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;changeset&#x2F;7519&quot;&gt;changeset that added a native &lt;code&gt;ActiveRecord#to_json&lt;&#x2F;code&gt; method&lt;&#x2F;a&gt;. Of course, I&#x27;m elated that JSON serialization is given first class attention now, since the raison d&#x27;être of Jsonifier and my Rails patch was to do just that. A little bit of me is selfishly disappointed since it means that Jsonifier has become quite obsolete!&lt;&#x2F;p&gt;
&lt;p&gt;But it is an excellent change, I look forward to patching it up (if DHH doesn&#x27;t beat me to it - there&#x27;ve been so much activity on the Rails trunk recently) so that the &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;activerecord&#x2F;lib&#x2F;active_record&#x2F;serializers&#x2F;json_serializer.rb?rev=7519&quot;&gt;JSON serializer&lt;&#x2F;a&gt; supports an &lt;code&gt;:include&lt;&#x2F;code&gt; options for including associations much like for &lt;code&gt;ActiveRecord#to_xml&lt;&#x2F;code&gt; and Jsonifier&#x27;s mixed in &lt;code&gt;to_json&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;ins&gt;Update: I&#x27;ve submitted a &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;9677&quot;&gt;patch for adding &lt;code&gt;:include&lt;&#x2F;code&gt; to &lt;code&gt;ActiveRecord#to_json&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. Please test it and give feedback or +1 ;).&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>ActiveRecord database :default &quot;gotcha&quot;</title>
    <published>2007-09-19T21:37:21+00:00</published>
    <updated>2007-09-19T21:37:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/09/19/activerecord-database-default-gotcha/"/>
    <id>https://chuyeow.wtf/2007/09/19/activerecord-database-default-gotcha/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/09/19/activerecord-database-default-gotcha/">&lt;p&gt;Note to self:&lt;&#x2F;p&gt;
&lt;p&gt;When a table column has a default value, such as for the &lt;code&gt;type_category&lt;&#x2F;code&gt; column&#x2F;attribute like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;t.string :type_category, :limit =&gt; 20, :nil =&gt; false, :default =&gt; &#x27;tv&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;a new instance of your ActiveRecord model will try and set the defaults from the database. Meaning:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Anime.new =&gt; #&amp;lt;Anime id: nil, type_category: &quot;tv&quot;...&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Courtesy of this in ActiveRecord::Base:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def attributes_from_column_definition
  self.class.columns.inject({}) do |attributes, column|
    attributes[column.name] = column.&lt;strong&gt;default&lt;&#x2F;strong&gt; unless column.name == self.class.primary_key
    attributes
  end
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, don&#x27;t get confused when your model validations (&lt;code&gt;validates_presence_of :type_category&lt;&#x2F;code&gt;) don&#x27;t seem to work when testing:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &quot;should require a type_category&quot; do
  @foo.attributes = valid_foo_attributes.except(:type_category)
  @foo.should have(1).error_on(:type_category)  # doesn&#x27;t work since @foo.type_category = &#x27;tv&#x27;
end&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Explicitly set it to nil or a blank value.&lt;&#x2F;p&gt;
&lt;p&gt;Sounds silly, but it&#x27;s a true story.&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>How to install Rails, the wrong way</title>
    <published>2007-07-30T17:34:25+00:00</published>
    <updated>2007-07-30T17:34:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/30/how-to-install-rails-the-wrong-way/"/>
    <id>https://chuyeow.wtf/2007/07/30/how-to-install-rails-the-wrong-way/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/30/how-to-install-rails-the-wrong-way/">&lt;p&gt;I&#x27;ve always thought the &lt;a href=&quot;http:&#x2F;&#x2F;rubyonrails.org&#x2F;down&quot;&gt;Rails installation instructions&lt;&#x2F;a&gt; on the official Rails website were pretty straightforward, so I couldn&#x27;t help laughing when I saw this chat transcript a friend copied and pasted for me:&lt;&#x2F;p&gt;
&lt;blockquote&gt;&lt;p&gt;[5:23:05 PM] X says: try so many times finally can le&lt;br &#x2F;&gt;
[5:23:23 PM] X says: it is not about the version or wat&lt;br &#x2F;&gt;
[5:23:46 PM] Y says: then what is the error?&lt;br &#x2F;&gt;
[5:24:22 PM] X says: the gem install rails--include-dependencies&lt;br &#x2F;&gt;
[5:24:37 PM] X says: &lt;strong&gt;between rails and --include got spacing&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;I know it&#x27;s mean to laugh but I&#x27;m not a carebear! I think it took him a day to install it despite having installed and uninstalled it for 2 whole months (don&#x27;t ask me why, but his environment kept getting borked).&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>logrotate and mongrel (mongrel_cluster)</title>
    <published>2007-07-16T13:45:21+00:00</published>
    <updated>2007-07-16T13:45:21+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/07/16/logrotate-and-mongrel-mongrel_cluster/"/>
    <id>https://chuyeow.wtf/2007/07/16/logrotate-and-mongrel-mongrel_cluster/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/07/16/logrotate-and-mongrel-mongrel_cluster/">&lt;p&gt;I&#x27;ve never actually explored log rotation tools in Linux and merely knew of the existence of &lt;a href=&quot;http:&#x2F;&#x2F;www.linuxcommand.org&#x2F;man_pages&#x2F;logrotate8.html&quot;&gt;logrotate&lt;&#x2F;a&gt; and left it at that until log sizes really became a problem. Turns out logrotate is amazingly easy to configure, and thanks to &lt;a href=&quot;http:&#x2F;&#x2F;www.atmos.org&#x2F;2007&#x2F;3&#x2F;22&#x2F;logrotate-and-mongrel&quot;&gt;this Logrotate and Mongrel blog post by Corey Donohoe&lt;&#x2F;a&gt; I have it setup for my Rails applications that are running on &lt;a href=&quot;http:&#x2F;&#x2F;mongrel.rubyforge.org&#x2F;&quot;&gt;Mongrel&lt;&#x2F;a&gt;. Here&#x27;s what my &lt;code&gt;&#x2F;etc&#x2F;logrotate.d&#x2F;mongrel_cluster&lt;&#x2F;code&gt; looks like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;var&#x2F;railsapps&#x2F;APP_NAME&#x2F;shared&#x2F;log&#x2F;production.log {
  daily
  rotate 28
  missingok
  compress
  sharedscripts
  postrotate
    for i in `ls &#x2F;var&#x2F;railsapps&#x2F;APP_NAME&#x2F;shared&#x2F;log&#x2F;*.pid`; do
      kill -USR2 `cat $i`
    done
  endscript
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&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>Nginx, PHP and a PHP FastCGI daemon init script</title>
    <published>2007-06-11T21:18:32+00:00</published>
    <updated>2007-06-11T21:18:32+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/06/11/nginx-php-and-a-php-fastcgi-daemon-init-script/"/>
    <id>https://chuyeow.wtf/2007/06/11/nginx-php-and-a-php-fastcgi-daemon-init-script/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/06/11/nginx-php-and-a-php-fastcgi-daemon-init-script/">&lt;p&gt;One of the things us ex-Apache httpd or ex-Lighttpd users have to get used to when installing &lt;a href=&quot;http:&#x2F;&#x2F;nginx.net&#x2F;&quot;&gt;nginx&lt;&#x2F;a&gt; is how there isn&#x27;t built-in FastCGI support for process spawning. While these means nginx is more lightweight and faster, it does mean that you have to manage your FastCGI processes yourself.&lt;&#x2F;p&gt;
&lt;p&gt;Having just upgraded to Ubuntu Feisty Fawn, I set to installing nginx and tried to get WordPress (which needs PHP, of course) running on it. Thanks to the new nginx package in the Feisty universe repository, getting nginx up and PHP (CGI version) and running is really straightforward. There&#x27;re &lt;a href=&quot;http:&#x2F;&#x2F;blog.dominiek.com&#x2F;articles&#x2F;2007&#x2F;5&#x2F;18&#x2F;bye-redskin-zdravstvujte-redstar-nginx-tips&#x2F;&quot;&gt;lots&lt;&#x2F;a&gt; of &lt;a href=&quot;http:&#x2F;&#x2F;www.urbanpuddle.com&#x2F;articles&#x2F;2007&#x2F;05&#x2F;09&#x2F;install-ruby-on-rails-on-ubuntu-feisty-fawn&quot;&gt;tutorials&lt;&#x2F;a&gt; to help you out as well.&lt;&#x2F;p&gt;
&lt;p&gt;So that&#x27;s that. The part that bugged me though, was how the tutorials always provided a script to start your PHP FastCGI processes, but never provided a way to ensure your FastCGI processes started up on a reboot (i.e. an init script). Once again, Google doesn&#x27;t disappoint, turning up this &lt;a href=&quot;http:&#x2F;&#x2F;www.mail-archive.com&#x2F;debian-bugs-dist@lists.debian.org&#x2F;msg352883.html&quot;&gt;php-cgi init script&lt;&#x2F;a&gt;. Tweak the init script a little, put it in &#x2F;etc&#x2F;init.d&#x2F;php-fastcgi, &lt;code&gt;sudo chmod +x &#x2F;etc&#x2F;init.d&#x2F;php-fastcgi&lt;&#x2F;code&gt;, run &lt;code&gt;sudo update-rc.d php-fastcgi defaults&lt;&#x2F;code&gt; and place the configuration for the script in &#x2F;etc&#x2F;default&#x2F;php-fastcgi, and you&#x27;re done. You now have a PHP FastCGI init script that spawns and kills your PHP FastCGI processes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; Lighttpd does come with a &lt;code&gt;spawn-fcgi&lt;&#x2F;code&gt; binary that does the same, but I&#x27;m having trouble finding a suitable init script for spawn-fcgi (only the Gentoo emerge seems to have the init script). Still, this script works and I didn&#x27;t really want to install lightty on my starving &lt;acronym title=&quot;Virtual Private Server&quot;&gt;VPS&lt;&#x2F;acronym&gt;.&lt;&#x2F;p&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;&#x2F;span&gt;&lt;p&gt;&lt;strong&gt;The init script: &#x2F;etc&#x2F;init.d&#x2F;php-fastcgi&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#! &#x2F;bin&#x2F;sh
### BEGIN INIT INFO
# Provides:          php-fastcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop php-cgi in external FASTCGI mode
# Description:       Start and stop php-cgi in external FASTCGI mode
### END INIT INFO
&lt;h1 id=&quot;author-kurt-zankl-email-protected&quot;&gt;Author: Kurt Zankl &amp;lt;[EMAIL PROTECTED]&amp;gt;&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;do-not-set-e&quot;&gt;Do NOT &quot;set -e&quot;&lt;&#x2F;h1&gt;
&lt;p&gt;PATH=&#x2F;sbin:&#x2F;usr&#x2F;sbin:&#x2F;bin:&#x2F;usr&#x2F;bin
DESC=&quot;php-cgi in external FASTCGI mode&quot;
NAME=php-fastcgi
DAEMON=&#x2F;usr&#x2F;bin&#x2F;php-cgi
PIDFILE=&#x2F;var&#x2F;run&#x2F;$NAME.pid
SCRIPTNAME=&#x2F;etc&#x2F;init.d&#x2F;$NAME
PHP_CONFIG_FILE=&#x2F;etc&#x2F;php5&#x2F;cgi&#x2F;php.ini&lt;&#x2F;p&gt;
&lt;h1 id=&quot;exit-if-the-package-is-not-installed&quot;&gt;Exit if the package is not installed&lt;&#x2F;h1&gt;
&lt;p&gt;[ -x &quot;$DAEMON&quot; ] || exit 0&lt;&#x2F;p&gt;
&lt;h1 id=&quot;read-configuration-variable-file-if-it-is-present&quot;&gt;Read configuration variable file if it is present&lt;&#x2F;h1&gt;
&lt;p&gt;[ -r &#x2F;etc&#x2F;default&#x2F;$NAME ] &amp;amp;&amp;amp; . &#x2F;etc&#x2F;default&#x2F;$NAME&lt;&#x2F;p&gt;
&lt;h1 id=&quot;load-the-verbose-setting-and-other-rcs-variables&quot;&gt;Load the VERBOSE setting and other rcS variables&lt;&#x2F;h1&gt;
&lt;p&gt;. &#x2F;lib&#x2F;init&#x2F;vars.sh&lt;&#x2F;p&gt;
&lt;h1 id=&quot;define-lsb-log-functions&quot;&gt;Define LSB log_* functions.&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;depend-on-lsb-base-3-0-6-to-ensure-that-this-file-is-present&quot;&gt;Depend on lsb-base (&amp;gt;= 3.0-6) to ensure that this file is present.&lt;&#x2F;h1&gt;
&lt;p&gt;. &#x2F;lib&#x2F;lsb&#x2F;init-functions&lt;&#x2F;p&gt;
&lt;h1 id=&quot;if-the-daemon-is-not-enabled-give-the-user-a-warning-and-then-exit&quot;&gt;If the daemon is not enabled, give the user a warning and then exit,&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;unless-we-are-stopping-the-daemon&quot;&gt;unless we are stopping the daemon&lt;&#x2F;h1&gt;
&lt;p&gt;if [ &quot;$START&quot; != &quot;yes&quot; -a &quot;$1&quot; != &quot;stop&quot; ]; then
log_warning_msg &quot;To enable $NAME, edit &#x2F;etc&#x2F;default&#x2F;$NAME and set START=yes&quot;
exit 0
fi&lt;&#x2F;p&gt;
&lt;h1 id=&quot;process-configuration&quot;&gt;Process configuration&lt;&#x2F;h1&gt;
&lt;p&gt;export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
DAEMON_ARGS=&quot;-q -b $FCGI_HOST:$FCGI_PORT -c $PHP_CONFIG_FILE&quot;&lt;&#x2F;p&gt;
&lt;p&gt;do_start()
{
# Return
#   0 if daemon has been started
#   1 if daemon was already running
#   2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test &amp;gt; &#x2F;dev&#x2F;null &lt;br &#x2F;&gt;
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON &lt;br &#x2F;&gt;
--background --make-pidfile --chuid $EXEC_AS_USER --startas $DAEMON -- &lt;br &#x2F;&gt;
$DAEMON_ARGS &lt;br &#x2F;&gt;
|| return 2
}&lt;&#x2F;p&gt;
&lt;p&gt;do_stop()
{
# Return
#   0 if daemon has been stopped
#   1 if daemon was already stopped
#   2 if daemon could not be stopped
#   other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM&#x2F;30&#x2F;KILL&#x2F;5 --pidfile $PIDFILE &amp;gt; &#x2F;dev&#x2F;null # --name $DAEMON
RETVAL=&quot;$?&quot;
[ &quot;$RETVAL&quot; = 2 ] &amp;amp;&amp;amp; return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently.  A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0&#x2F;30&#x2F;KILL&#x2F;5 --exec $DAEMON
[ &quot;$?&quot; = 2 ] &amp;amp;&amp;amp; return 2
# Many daemons don&#x27;t delete their pidfiles when they exit.
rm -f $PIDFILE
return &quot;$RETVAL&quot;
}
case &quot;$1&quot; in
start)
[ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_daemon_msg &quot;Starting $DESC&quot; &quot;$NAME&quot;
do_start
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_end_msg 1 ;;
esac
;;
stop)
[ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_daemon_msg &quot;Stopping $DESC&quot; &quot;$NAME&quot;
do_stop
case &quot;$?&quot; in
0|1) [ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_end_msg 0 ;;
2) [ &quot;$VERBOSE&quot; != no ] &amp;amp;&amp;amp; log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg &quot;Restarting $DESC&quot; &quot;$NAME&quot;
do_stop
case &quot;$?&quot; in
0|1)
do_start
case &quot;$?&quot; in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo &quot;Usage: $SCRIPTNAME {start|stop|restart|force-reload}&quot; &amp;gt;&amp;amp;2
exit 3
;;
esac&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Config file for init script (the init script looks for this): &#x2F;etc&#x2F;default&#x2F;php-fastcgi&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;START=yes
&lt;h1 id=&quot;which-user-runs-php-default-www-data&quot;&gt;Which user runs PHP? (default: www-data)&lt;&#x2F;h1&gt;
&lt;p&gt;EXEC_AS_USER=www-data&lt;&#x2F;p&gt;
&lt;h1 id=&quot;host-and-tcp-port-for-fastcgi-listener-default-localhost-9000&quot;&gt;Host and TCP port for FASTCGI-Listener (default: localhost:9000)&lt;&#x2F;h1&gt;
&lt;p&gt;FCGI_HOST=localhost
FCGI_PORT=9000&lt;&#x2F;p&gt;
&lt;h1 id=&quot;environment-variables-which-are-processed-by-php&quot;&gt;Environment variables, which are processed by PHP&lt;&#x2F;h1&gt;
&lt;p&gt;PHP_FCGI_CHILDREN=4
PHP_FCGI_MAX_REQUESTS=1000&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;nginx config file: &#x2F;etc&#x2F;nginx&#x2F;nginx.conf&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  &#x2F;var&#x2F;www&#x2F;chuyeow.wtf$fastcgi_script_name;
  include        &#x2F;etc&#x2F;nginx&#x2F;fastcgi.conf;
}&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;My fastcgi.conf file (I&#x27;m not sure I need everything here...)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
&lt;p&gt;fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;&lt;&#x2F;p&gt;
&lt;p&gt;fastcgi_param  GATEWAY_INTERFACE  CGI&#x2F;1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;&lt;&#x2F;p&gt;
&lt;p&gt;fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;php-only-required-if-php-was-built-with-enable-force-cgi-redirect&quot;&gt;PHP only, required if PHP was built with --enable-force-cgi-redirect&lt;&#x2F;h1&gt;
&lt;p&gt;fastcgi_param  REDIRECT_STATUS    200;&lt;&#x2F;code&gt;&lt;&#x2F;pre&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>DRYing up link_to_remote for degradable URLs</title>
    <published>2007-03-24T23:20:08+00:00</published>
    <updated>2007-03-24T23:20:08+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/"/>
    <id>https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2007/03/24/drying-up-link_to_remote-for-degradable-urls/">&lt;p&gt;I like to keep my links in my Rails applications that make AJAX requests degradable in non-JavaScript browsers so I often find myself doing this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
link_to_remote &#x27;Show details&#x27;,
  { :url =&gt; { :action =&gt; &#x27;show&#x27;, :id =&gt; post.id } },
  { :href =&gt; url_for({ :action =&gt; &#x27;show&#x27;, :id =&gt; post.id }) }&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows me to get HTML links like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;a href=&quot;http:&#x2F;&#x2F;www.example.com&#x2F;posts&#x2F;show&#x2F;123&quot; onclick=&quot;...&quot;&amp;gt;Show details&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;instead of the usual (if the :href parameter is not specified):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;a href=&quot;#&quot; onclick=&quot;...&quot;&amp;gt;Show details&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You&#x27;ve probably already noticed the duplication right there in the &lt;code&gt;:url&lt;&#x2F;code&gt; key of the 2nd parameter (options) and the &lt;code&gt;:href&lt;&#x2F;code&gt; key of the 3rd parameter (HTML options) that litters my &lt;acronym title=&quot;embedded Ruby&quot;&gt;Erb&lt;&#x2F;acronym&gt; templates where link_to_remote calls are prevalent. I got tired of editing and copying and pasting the &lt;code&gt;url_for&lt;&#x2F;code&gt; parameters so I monkey patched Rails&#x27; PrototypeHelper class in ActionPack (&lt;code&gt;actionpack&#x2F;lib&#x2F;action_view&#x2F;helpers&#x2F;prototype_helper.rb&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;To do this, I had to replace Rails&#x27; &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; method definition. Thanks to living and breathing code examples in Rails that do this, I was able to promptly come up with this module that I placed into the &lt;code&gt;lib&#x2F;&lt;&#x2F;code&gt; directory of my Rails application and &lt;code&gt;require&lt;&#x2F;code&gt; it in my &lt;code&gt;environment.rb&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
module Bezurk #:nodoc:
  module ActionView #:nodoc:
    module PrototypeHelperExtensions
      def self.included(base)
        base.alias_method_chain :link_to_remote, :degradation
      end
&lt;pre&gt;&lt;code&gt;  def link_to_remote_with_degradation(name, options = {}, html_options = {})
    html_options[:href] = url_for(options[:url]) if !html_options.has_key?(:href)
    link_to_remote_without_degradation(name, options, html_options)
  end
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;end
end&lt;&#x2F;p&gt;
&lt;p&gt;ActionView::Helpers::PrototypeHelper.send(:include,
Bezurk::ActionView::PrototypeHelperExtensions)&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The modification to &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; itself is dead simple: it checks for the non-existence of a &lt;code&gt;:href&lt;&#x2F;code&gt; key in the &lt;code&gt;html_options&lt;&#x2F;code&gt; parameter and sets the &lt;code&gt;:href&lt;&#x2F;code&gt; option in the &lt;code&gt;html_options&lt;&#x2F;code&gt; parameter hash to the &lt;code&gt;url_for&lt;&#x2F;code&gt; the &lt;code&gt;:url&lt;&#x2F;code&gt; value in the &lt;code&gt;options&lt;&#x2F;code&gt; parameter hash. It then calls the original &lt;code&gt;link_to_remote&lt;&#x2F;code&gt; to do what it does best.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve submitted a (trivially simple) patch to Rails in my opened &lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;ticket&#x2F;7904&quot;&gt;ticket #7904 - DRY up link_to_remote for degradable URLs&lt;&#x2F;a&gt;. Let&#x27;s hope this makes it in so I can kill my monkey patch!&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>Job Ad: Java Web Developer for Bezurk</title>
    <published>2006-09-22T20:37:35+00:00</published>
    <updated>2006-09-22T20:37:35+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/"/>
    <id>https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/09/22/job-ad-java-web-developer-for-bezurk/">&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;bezurk.com&#x2F;&quot;&gt;We&lt;&#x2F;a&gt;&#x27;re on the lookout for a &lt;a href=&quot;http:&#x2F;&#x2F;singapore.craigslist.org&#x2F;sof&#x2F;209737528.html&quot;&gt;Java Web Developer (ad on Craigslist)&lt;&#x2F;a&gt;. I managed to get &quot;Ruby on Rails&quot; into the ad copy somewhere heh - it gets kinda lonely working in a development team of Java heads. Anyway, we&#x27;re looking for a great Java developer to work with us in Singapore - if you&#x27;re up for it, &lt;a href=&quot;mailto:devel@bezurk.com&quot;&gt;send us your resume&lt;&#x2F;a&gt;. I would really like to get someone with some interest in Rails development to work together with on some upcoming (Rails) projects (you know, like after all the real work is done).&lt;&#x2F;p&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>Some functional testing gotchas in Ruby on Rails</title>
    <published>2006-09-03T20:35:52+00:00</published>
    <updated>2006-09-03T20:35:52+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/09/03/some-functional-testing-gotchas-in-ruby-on-rails/"/>
    <id>https://chuyeow.wtf/2006/09/03/some-functional-testing-gotchas-in-ruby-on-rails/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/09/03/some-functional-testing-gotchas-in-ruby-on-rails/">&lt;p&gt;I&#x27;ve been writing lots of functional tests lately and came across several unexpected gotchas. Seeing as how forgetful I am recently, I&#x27;ll jot them down here (and hopefully benefit anyone else who comes across the same problems).&lt;&#x2F;p&gt;
&lt;h3&gt;Testing flash.now&lt;&#x2F;h3&gt;
&lt;p&gt;Testing the contents of the flash.now, somewhat surprisingly, can&#x27;t be done with code like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;assert_equal &#x27;Unable to activate your account.&#x27;,
  flash.now[:error]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;flash.now[:error]&lt;&#x2F;code&gt; would be &lt;code&gt;nil&lt;&#x2F;code&gt;, in your functional test, and a quick lookup on Google brought me to &lt;a href=&quot;http:&#x2F;&#x2F;wiki.rubyonrails.org&#x2F;rails&#x2F;pages&#x2F;HowToTestFlash.Now&#x2F;&quot;&gt;HowToTestFlash.Now on the Rails wiki&lt;&#x2F;a&gt;. Apparently, Rails renders the flash in the view and then proceeds to clear the contents of flash.now (so it isn&#x27;t accessible in your functional test). So, you&#x27;d have to test the contents of the rendered page, instead of testing the flash itself:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;assert_tag :tag =&gt; &#x27;div&#x27;,
               :attributes =&gt; { :class =&gt; &#x27;flash error&#x27; },
               :content =&gt; &#x27;Unable to activate your account.&#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3&gt;Asserting cookies&lt;&#x2F;h3&gt;
&lt;p&gt;This one&#x27;s particularly annoying - trying to assert that cookies are set by your controllers. Unlike what was written in the &lt;a href=&quot;http:&#x2F;&#x2F;manuals.rubyonrails.com&#x2F;read&#x2F;chapter&#x2F;28&quot;&gt;Rails manual on testing&lt;&#x2F;a&gt; (granted, it&#x27;s rather well-known that the manuals are somewhat outdated), you cannot retrieve cookies using a Symbol as an index into the &lt;code&gt;cookies&lt;&#x2F;code&gt; hash in your functional tests.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;cookies[:auth_token] = {
  :value =&gt; session[:user].remember_token,
  :expires =&gt; session[:user].remember_token_expires_at
}
&lt;p&gt;assert cookies[:auth_token]  # nil
assert cookies[&#x27;auth_token&#x27;]  # This works.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;http:&#x2F;&#x2F;www.pluitsolutions.com&#x2F;&quot;&gt;Herry&lt;&#x2F;a&gt; for &lt;a href=&quot;http:&#x2F;&#x2F;www.pluitsolutions.com&#x2F;2006&#x2F;08&#x2F;02&#x2F;rails-functional-test-with-cookie&#x2F;&quot;&gt; pointing this out &lt;&#x2F;a&gt; - it saved me an exercise in frustration.&lt;&#x2F;p&gt;
&lt;p&gt;Yet another cookie testing gotcha is testing for the deletion of cookies (example use case: deleting a users cookie after he logs out). So you may do this in your controller:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;cookies.delete :auth_token&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And expect this to pass in your test:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;assert_nil cookies[&#x27;auth_token&#x27;]&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But nope, instead of setting the cookie to &lt;code&gt;nil&lt;&#x2F;code&gt;, the cookie is actually emptied.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;assert cookies[&#x27;auth_token&#x27;].empty?  # This works.&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I just used wrote my own custom assertion (there is an assert_cookie plugin around but I didn&#x27;t think this justified adding another plugin to the application, not just yet):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def assert_no_cookie(cookie_name)
  cookies[cookie_name].nil?
    || cookies[cookie_name].empty?
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;ins&gt;Update: as it turns out, &lt;code&gt;assert_no_cookie&lt;&#x2F;code&gt; and &lt;code&gt;assert_cookie_equals&lt;&#x2F;code&gt; exist as custom assertions in ActionPack (&lt;a href=&quot;http:&#x2F;&#x2F;dev.rubyonrails.org&#x2F;browser&#x2F;trunk&#x2F;actionpack&#x2F;lib&#x2F;action_controller&#x2F;assertions&#x2F;deprecated_assertions.rb&quot;&gt;source&lt;&#x2F;a&gt;), but have been deprecated in favor of the &lt;code&gt;cookies&lt;&#x2F;code&gt; collection. Still, looking up the &lt;code&gt;cookies&lt;&#x2F;code&gt; collection with a Symbol but having it return &lt;code&gt;nil&lt;&#x2F;code&gt; is unexpected behavior considering the inline documentation says it should work.&lt;&#x2F;ins&gt;&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>From Typo to Mephisto</title>
    <published>2006-09-01T20:34:25+00:00</published>
    <updated>2006-09-01T20:34:25+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/09/01/from-typo-to-mephisto/"/>
    <id>https://chuyeow.wtf/2006/09/01/from-typo-to-mephisto/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/09/01/from-typo-to-mephisto/">&lt;p&gt;So with the usual fickle-mindedness, I&#x27;ve changed my blog software from &lt;a href=&quot;http:&#x2F;&#x2F;typosphere.org&#x2F;&quot;&gt;Typo&lt;&#x2F;a&gt; to &lt;a href=&quot;http:&#x2F;&#x2F;mephistoblog.com&#x2F;&quot;&gt;Mephisto&lt;&#x2F;a&gt;. Well, it wasn&#x27;t so much based on a whim - there were some reasons I wanted to stop using Typo:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For some reason, Typo is very unstable for me on my VPS with 160MB RAM. I deploy Typo on a mongrel_cluster of 2 mongrels, fronting it with Apache 2.2 + mod_proxy_balancer, and all 160MB RAM &lt;strong&gt;and&lt;&#x2F;strong&gt; 192MB of swap is used up whenever I post an article or sweep the cache. Comments also take noticeably longer to post on my blog than on other Typo blogs. I&#x27;m not sure what exactly I&#x27;ve done wrong.&lt;&#x2F;li&gt;
&lt;li&gt;I often get an obscure NilClass error that screws up the front page whenever pages are regenerated (often caused by someone posting a comment or an article).&lt;&#x2F;li&gt;
&lt;li&gt;Changing the blog&#x27;s design requires one to create or edit an existing Typo theme - I kinda missed WordPress&#x27;s Web-based template editing. This was a significant roadblock to me ever changing the look and feel of my Typo blog.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Coincidentally, my urge to swap to Mephisto coincided with the &lt;a href=&quot;http:&#x2F;&#x2F;mephistoblog.com&#x2F;2006&#x2F;8&#x2F;31&#x2F;mephisto-immortus-released&quot;&gt;release of mephisto 0.6 (Immortus)&lt;&#x2F;a&gt; just today, and after some minor hiccups, I managed to get Mephisto up and running with my articles imported from Typo. (Still couldn&#x27;t get Capistrano to play well though, which I&#x27;m guessing is due to Rails version conflicts - I guess I&#x27;ll just have to do with the release version.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;http:&#x2F;&#x2F;mephisto.stikipad.com&#x2F;&quot;&gt;Documentation&lt;&#x2F;a&gt; is rather sparse at the moment, especially on how to &lt;a href=&quot;http:&#x2F;&#x2F;mephisto.stikipad.com&#x2F;help&#x2F;show&#x2F;Converting+Typo+to+Mephisto&quot;&gt;convert from Typo to Mephisto&lt;&#x2F;a&gt; (I updated that wiki page while I was there). I dug around in Mephisto 0.6â€™s source and found the converters in vendor&#x2F;plugins&#x2F;mephisto_converter. Not sure if there is a web interface to this - either way, things worked almost perfectly just running this command:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;script&#x2F;runner &quot;Mephisto.convert_from :typo&quot; -e production&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You need to create a typo entry in database.yml that points to your existing Typo database. Also, the conversion will fail if any of your Typo users and email addresses are the same as the default Mephisto user admin. To avoid this just change the Mephisto user(s) login and email to something else.&lt;&#x2F;p&gt;
&lt;p&gt;So there&#x27;s that, hopefully some time this year I&#x27;ll update the look and feel.&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Application error (Rails) on Google search results</title>
    <published>2006-08-15T20:09:22+00:00</published>
    <updated>2006-08-15T20:09:22+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/15/application-error-rails-on-google-search-results/"/>
    <id>https://chuyeow.wtf/2006/08/15/application-error-rails-on-google-search-results/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/15/application-error-rails-on-google-search-results/">&lt;p&gt;I did a &lt;a href=&quot;http:&#x2F;&#x2F;www.google.com.sg&#x2F;search?q=rimuhosting&quot;&gt;search on Google for &quot;Rimuhosting&quot;&lt;&#x2F;a&gt; today, some time after I &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;articles&#x2F;2006&#x2F;08&#x2F;10&#x2F;moving-to-rimuhosting-vps&quot;&gt;signed up with them&lt;&#x2F;a&gt;, and hey, there&#x27;s my blog in &lt;em&gt;3rd spot&lt;&#x2F;em&gt; - is that some mad &lt;acronym title=&quot;Search Engine Optimization&quot;&gt;SEO&lt;&#x2F;acronym&gt; skillz or what. And then &quot;oooh, there&#x27;s an &#x27;Application error (Rails)&#x27; result coming out, that&#x27;s not good&quot;.&lt;&#x2F;p&gt;
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;rimuhosting-google-search-rails-error.png&quot; alt=&quot;&#x27;Application error (Rails)&#x27; on Google&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 thought it was amusing - Google must have crawled my site just as I had deployment troubles (yeah it was a &lt;em&gt;smart&lt;&#x2F;em&gt; move leaving MySQL to it&#x27;s default settings &lt;em&gt;and&lt;&#x2F;em&gt; using the InnoDB storage engine on a memory-starved VPS). All seems fine now though I&#x27;m still somewhat amazed at the hungry &lt;a href=&quot;http:&#x2F;&#x2F;mongrel.rubyforge.org&#x2F;&quot;&gt;Mongrels&lt;&#x2F;a&gt; (at 25-40MB per Mongrel process, these things run more like St. Bernards). (A shout out to &lt;a href=&quot;http:&#x2F;&#x2F;ryandaigle.com&#x2F;&quot;&gt;Ryan Daigle&lt;&#x2F;a&gt; who has been giving me some Rails deployment advice.)&lt;&#x2F;p&gt;
&lt;p&gt;By the way, the &quot;mad &lt;acronym title=&quot;Search Engine Optimization&quot;&gt;SEO&lt;&#x2F;acronym&gt; skillz&quot; comment was a joke, I wasn&#x27;t at all surprised to be honest, Google just loves blogs (and they still do, after all this time of I&#x27;ve been not blogging).&lt;&#x2F;p&gt;
</content>
  </entry>
  <entry>
    <title>Moving to Rimuhosting VPS</title>
    <published>2006-08-10T19:54:28+00:00</published>
    <updated>2006-08-10T19:54:28+00:00</updated>
    <author><name>Chu Yeow</name></author>
    <link rel="alternate" type="text/html" href="https://chuyeow.wtf/2006/08/10/moving-to-rimuhosting-vps/"/>
    <id>https://chuyeow.wtf/2006/08/10/moving-to-rimuhosting-vps/</id>
    <content type="html" xml:base="https://chuyeow.wtf/2006/08/10/moving-to-rimuhosting-vps/">&lt;p&gt;After being plagued with performance issues running &lt;a href=&quot;http:&#x2F;&#x2F;www.typosphere.org&#x2F;&quot;&gt;Typo&lt;&#x2F;a&gt; (the blog software on which this blog currently runs) on &lt;a href=&quot;http:&#x2F;&#x2F;dreamhost.com&#x2F;&quot;&gt;Dreamhost&lt;&#x2F;a&gt;, I decided it was time to give in and get a &lt;acronym title=&quot;Virtual Private Server&quot;&gt;VPS&lt;&#x2F;acronym&gt; once again. I was previously with &lt;a href=&quot;http:&#x2F;&#x2F;linode.com&#x2F;&quot;&gt;Linode.com&lt;&#x2F;a&gt; (they have a great control panel where you can drop in the distro you want - still have screenshots somewhere for an unpublished post), and then &lt;a href=&quot;http:&#x2F;&#x2F;jvds.com&#x2F;&quot;&gt;JVDS&lt;&#x2F;a&gt; (good hosting, usually quick replies to my support tickets, but slow to push out a VPS control panel they&#x27;ve been promising), running Gentoo on both VPSs. Right now, I&#x27;m on a shared hosting plan with &lt;a href=&quot;http:&#x2F;&#x2F;dreamhost.com&#x2F;&quot;&gt;Dreamhost&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Well, &lt;a href=&quot;http:&#x2F;&#x2F;dreamhost.com&#x2F;&quot;&gt;Dreamhost&lt;&#x2F;a&gt; has been good to me - I got so many referral credits from them that they paid for my subscription many times over after I &lt;a href=&quot;https:&#x2F;&#x2F;chuyeow.wtf&#x2F;archives&#x2F;2004&#x2F;10&#x2F;11&#x2F;dreamhost-hosting-at-077month&#x2F;&quot;&gt;posted about their $0.77&#x2F;month offer&lt;&#x2F;a&gt;. Unfortunately, Typo seems to be quite a monster (compared to Wordpress), and database access is &lt;a href=&quot;http:&#x2F;&#x2F;blog.zacharypinter.com&#x2F;articles&#x2F;2006&#x2F;03&#x2F;03&#x2F;switching-from-dreamhost-to-textdrive&quot;&gt;purportedly (and observably) slow on Dreamhost&lt;&#x2F;a&gt;. Still, Dreamhost is a great host for shared hosting, I&#x27;m sticking with them for delivering more static content. A VPS just makes sense now that I&#x27;ve been tinkering more with Ruby on Rails, plus which geek wouldn&#x27;t admit it just feels more &lt;em&gt;right&lt;&#x2F;em&gt; to be in full control of your server (well, it&#x27;s root on a virtual machine, but still root).&lt;&#x2F;p&gt;
&lt;p&gt;This time around, I chose &lt;a href=&quot;http:&#x2F;&#x2F;rimuhosting.com&#x2F;&quot;&gt;Rimuhosting&lt;&#x2F;a&gt;, a New Zealand-based hosting company (servers are US-based, of course), and here&#x27;s why (I did some research once again on &lt;a href=&quot;&quot;&gt;WebHostingTalk&lt;&#x2F;a&gt; and asked some people their experiences with their webhosts):&lt;&#x2F;p&gt;
&lt;p&gt;Pros:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Fairly affordable prices - I got their cheapest MiroVPS1 plan, which goes for $19.95&#x2F;month and get 30GB of transfer and 96MB of RAM (which &lt;em&gt;could&lt;&#x2F;em&gt; be a problem, but upgrading seems easy enough anyway from what they say on their site). Comparing to several other VPS hosts like &lt;a href=&quot;http:&#x2F;&#x2F;unixshell.com&#x2F;&quot;&gt;unixshell&lt;&#x2F;a&gt;, Tektonic.net, &lt;a href=&quot;http:&#x2F;&#x2F;www.serveraxis.com&#x2F;&quot;&gt;ServerAxis&lt;&#x2F;a&gt;, their plans are somewhat mid-range.&lt;&#x2F;li&gt;
&lt;li&gt;Their reputation is great. Yup, I&#x27;ve heard and read only good things about them, something that&#x27;s quite hard to find in the world of web hosting. We use them at work to setup servers sometimes too.&lt;&#x2F;li&gt;
&lt;li&gt;Seems to be run by competent people - they have a &lt;a href=&quot;http:&#x2F;&#x2F;bliki.rimuhosting.com&#x2F;&quot;&gt;bliki&lt;&#x2F;a&gt; (blog + wiki) with some nice posts. The one that really caught my eye is the one on their &lt;a href=&quot;http:&#x2F;&#x2F;bliki.rimuhosting.com&#x2F;space&#x2F;knowledgebase&#x2F;linux&#x2F;miscapplications&#x2F;ruby+on+rails&quot;&gt;Ruby on Rails hosting stack&lt;&#x2F;a&gt;. Not that I&#x27;d use it since I&#x27;m on Ubuntu, but it shows that the folks at Rimuhosting are up-to-date.&lt;&#x2F;li&gt;
&lt;li&gt;They run &lt;a href=&quot;http:&#x2F;&#x2F;www.cl.cam.ac.uk&#x2F;Research&#x2F;SRG&#x2F;netos&#x2F;xen&#x2F;&quot;&gt;Xen&lt;&#x2F;a&gt;, which &lt;a href=&quot;http:&#x2F;&#x2F;deepak.jois.name&#x2F;&quot;&gt;Deepak&lt;&#x2F;a&gt;, among others, tells me is the most efficient server virtualization software. Yeah, whatever, score one for statistics (and lies).&lt;&#x2F;li&gt;
&lt;li&gt;Support is reasonably fast - got replies to my pre-sales queries reasonably fast (more than a few hours, but it wasn&#x27;t during working hours anyway). Of course, I&#x27;ll have to see how it goes now that I&#x27;m a real customer.&lt;&#x2F;li&gt;
&lt;li&gt;A simple web-based control panel where I can reboot the VPS. It&#x27;s no &lt;a href=&quot;http:&#x2F;&#x2F;www.swsoft.com&#x2F;en&#x2F;products&#x2F;virtuozzo&#x2F;tools&#x2F;vzpp&#x2F;&quot;&gt;Virtuozzo Power Panels&lt;&#x2F;a&gt;, but it&#x27;s enough. JVDS didn&#x27;t have one and it started to get old sending support tickets to do a reboot.
&lt;div class=&quot;img&quot;&gt;&lt;img src=&quot;&#x2F;assets&#x2F;rimuhosting-vps-cp.png&quot; alt=&quot;Screenshot of Rimuhosting VPS control panel&quot; &#x2F;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;br style=&quot;clear:both&quot; &#x2F;&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;They don&#x27;t support &lt;a href=&quot;http:&#x2F;&#x2F;gentoo.org&#x2F;&quot;&gt;Gentoo&lt;&#x2F;a&gt;, my Linux distro of choice. Only RHEL, Ubuntu, Debian and Fedora Core are supported. I went with Ubuntu, not having much experience with it (excluding a brief affair with Debian). I was wary of this at first, but my fears of bungling around with an unfamiliar distro have vanished after I saw how easy it is to install stuff with apt-get, and things are &lt;em&gt;not&lt;&#x2F;em&gt; placed in weird places in the filesystem hierarchy. I think I could get used to it, this &quot;not compiling everything that moves&quot; idea ;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;serveraxis.com&#x2F;vds.php?ps=1&quot;&gt;ServerAxis&lt;&#x2F;a&gt; supports Gentoo, and offers much better &quot;value for money&quot;, except that their lowest priced plan is much higher ($30). But you get &lt;strong&gt;512MB RAM&lt;&#x2F;strong&gt;, 200GB RAM, and &lt;strong&gt;5 IP addresses&lt;&#x2F;strong&gt;... Too bad I&#x27;d rather pay out of my PayPal funds.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Well, less blogging, more server migration. Actually the application installs are mostly done. I&#x27;ve never had apt-get play so nice back when I was experimenting with Debian - just&lt;br &#x2F;&gt;
&lt;typo :code&gt;apt-get install [package]&lt;&#x2F;typo&gt; and things are installed quite cleanly (keyword: &quot;cleanly&quot;). I think this may grow on me (yeah yeah laugh and point at the Ubuntu noob) - perhaps you don&#x27;t need to compile everything (&lt;em&gt;gasp&lt;&#x2F;em&gt;, I said it!).&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>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>
</feed>
