<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>redemption in a blog &#187; Open Source</title>
	<atom:link href="http://blog.codefront.net/category/open-source/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codefront.net</link>
	<description>Rails, Firefox, Anime, Mac</description>
	<lastBuildDate>Tue, 24 Jan 2012 01:47:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Setting up virtualization on Ubuntu with KVM</title>
		<link>http://blog.codefront.net/2010/02/01/setting-up-virtualization-on-ubuntu-with-kvm/</link>
		<comments>http://blog.codefront.net/2010/02/01/setting-up-virtualization-on-ubuntu-with-kvm/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 14:18:13 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Operating Systems]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1271</guid>
		<description><![CDATA[These instructions have been tested on Ubuntu 9.10 (Karmic) 64-bit. Skip right to the instructions if you&#8217;re short on time. After being a happy Xen user for several years now, I&#8217;ve recently had to switch to an alternative virtualization solution. My colleague Arun (@iamclovin) actually struggled for a week with Xen VMs that locked up [...]]]></description>
			<content:encoded><![CDATA[<p>These instructions have been tested on <strong>Ubuntu 9.10 (Karmic) 64-bit</strong>. <a href="#kvm_guide_start">Skip right to the instructions</a> if you&#8217;re short on time.</p>
<p>After being a <a href="http://blog.codefront.net/2007/06/26/installing-xen-on-ubuntu-feisty-fawn-the-complete-newbies-guide/">happy Xen user</a> for several years now, I&#8217;ve recently had to switch to an alternative virtualization solution. My colleague Arun (<a href="http://twitter.com/iamclovin">@iamclovin</a>) actually struggled for a week with Xen VMs that locked up on Hardy; we&#8217;ve had much success with Hardy and Xen before, so we attributed it to a hardware problem since these were our first blade servers.</p>
<p>Out of ideas, we tried Karmic (Ubuntu 9.10) only to discover that Xen support via the apt package system is gone. I went down the path of compiling a <a href="http://wiki.xensource.com/xenwiki/XenParavirtOps">paravirt_ops</a> Dom0 kernel (<a href="http://www.itkovian.net/base/the-xen-hypervisor-with-ubuntu-karmic-koala/">this article</a> was <em>very</em> useful) but ended up deciding the process took far too long despite being successful.</p>
<p>With <a href="http://news.cnet.com/8301-13580_3-9867657-39.html">KVM gaining official support from Ubuntu</a> as <strong>the</strong> virtualization solution, I ended up ditching Xen and switching to <a href="http://www.linux-kvm.org/">KVM</a> for these new servers on Karmic. The rest of the entry is a step-by-step guide on setting up KVM VMs on a Ubuntu server; I&#8217;m putting this down because like all wikis, the <a href="https://help.ubuntu.com/community/KVM">Ubuntu KVM wiki</a> has grown a little too organically to be useful.</p>
<h3 id="kvm_guide_start">Preparing a host server for KVM</h3>
<ol>
<li>
    Update and upgrade apt packages (use your own discretion on whether this is necessary):</p>
<pre><code>aptitude update &#038;&#038; aptitude dist-upgrade</code></pre>
</li>
<li>
    Check whether CPU supports hardware virtualization:</p>
<pre><code>egrep '(vmx|svm)' --color=always /proc/cpuinfo</code></pre>
<p>    You should see lines with either &#8220;vmx&#8221; or &#8220;svm&#8221; highlighted.
  </li>
<li>
    Install these packages:</p>
<pre><code>aptitude install kvm libvirt-bin ubuntu-vm-builder bridge-utils</code></pre>
<p>    If you see a <code>FATAL: Error inserting kvm_intel</code> message during installation, it means that virtualization is not enabled in your machine&#8217;s BIOS. You&#8217;ll need to reboot your machine, enter the BIOS setup and enable virtualization (you&#8217;ll have to hunt for the option).<br />
    <a href="http://blog.codefront.net/wp-content/uploads/2010/02/BIOS-virtualization-option.png"><img src="http://blog.codefront.net/wp-content/uploads/2010/02/BIOS-virtualization-option.png" alt="" title="BIOS virtualization option" width="399" height="243" class="aligncenter size-full wp-image-1283" /></a><br />
    After enabling virtualization in the BIOS and rebooting, run:</p>
<pre><code>modprobe kvm-intel</code></pre>
<p>    There should be no error shown (in fact, no console response).
  </li>
<li>
    Optionally, install virt-top, a top-like tool for your VMs:</p>
<pre><code>aptitude install virt-top</code></pre>
</li>
<li>
    Verify that you can connect to the hypervisor:</p>
<pre><code>virsh -c qemu:///system list</code></pre>
<p>    You should see something like this:</p>
<pre><code>Connecting to uri: qemu:///system
 Id Name                 State
 ----------------------------------</code></pre>
</li>
<li>
    Setup a network bridge on the server for VMs. Edit <code>/etc/network/interfaces</code> so it looks like this (use your own IPs):</p>
<pre><code>auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto br0
iface br0 inet static
 address 192.168.1.222
 netmask 255.255.255.0
 network 192.168.1.0
 broadcast 192.168.1.255
 gateway 192.168.1.167
 bridge_ports eth0
 bridge_stp off
 bridge_fd 9
 bridge_hello 2
 bridge_maxage 12
 bridge_maxwait 0</code></pre>
</li>
<li>
    Make sure that you have a direct console to the server because you&#8217;re going to restart networking:</p>
<pre><code>/etc/init.d/networking restart</code></pre>
</li>
<li>
    Verify that your changes took place with <code>ifconfig</code>. You should see 2 entries like these:</p>
<pre><code>br0       Link encap:Ethernet  HWaddr 00:11:22:33:44:55
          inet addr:192.168.1.215  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::223:aeff:fefe:1f14/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1099 errors:0 dropped:0 overruns:0 frame:0
          TX packets:50 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:74665 (74.6 KB)  TX bytes:6223 (6.2 KB)

eth0      Link encap:Ethernet  HWaddr 00:66:77:88:99:00
          inet6 addr: fe80::223:aeff:fefe:1f14/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4939 errors:0 dropped:0 overruns:0 frame:0
          TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:532798 (532.7 KB)  TX bytes:5585 (5.5 KB)
          Interrupt:36 Memory:da000000-da012800</code></pre>
</li>
</ol>
<h3>Setting up a VM</h3>
<ol>
<li>
    Setup a VM with <code>vmbuilder</code>:</p>
<pre><code>vmbuilder kvm ubuntu \
    -v \
    --suite=karmic \
    --libvirt=qemu:///system \
    --arch=amd64 \
    --cpus=2 \
    --mem=2048 \
    --swapsize=4096 \
    --rootsize=20480 \
    --flavour=server \
    --hostname=billiejean \
    --ip=192.168.1.240 \
    --mask=255.255.255.0 \
    --net=192.168.1.0 \
    --bcast=192.168.1.255 \
    --gw=192.168.1.167 \
    --dns='202.157.163.157 202.157.131.118' \
    --bridge=br0 \
    --mirror=http://archive.ubuntu.com/ubuntu \
    --components='main,universe' \
    --addpkg=openssh-server \
    --user=administrator \
    --pass=icanhaspasswd \
    --dest=/root/vm-billiejean \
    --tmpfs=-</code></pre>
<p>    The options you need to care about are:</p>
<ol>
<li><code>suite</code>: Version of Ubuntu to install (e.g. karmic, hardy).</li>
<li><code>cpus</code>: Number of CPUs to assign to VM.</li>
<li><code>mem</code>: Amount of RAM in MB to assign to VM.</li>
<li><code>swapsize</code>: Size of swap in MB of VM.</li>
<li><code>rootsize</code>: Size of root filesystem in MB of VM.</li>
<li><code>flavour</code>: The &#8220;flavour&#8221; of kernel to use in the VM. Either &#8220;virtual&#8221; or &#8220;server&#8221;.</li>
<li><code>hostname</code>: Hostname of VM.</li>
<li><code>ip</code>: IP address of VM.</li>
<li><code>mask</code>: Netmask of VM.</li>
<li><code>net</code>: Network of VM.</li>
<li><code>bcast</code>: Broadcast address of VM.</li>
<li><code>gw</code>: Gateway of VM.</li>
<li><code>dns</code>: DNS server(s) for VM.</li>
<li><code>addpkg</code>: APT packages to install in the VM. openssh-server is needed so that we can login to the VM to setup the virsh console.</li>
<li><code>user</code> and <code>pass</code>: User account that&#8217;s setup for you to access the VM.</li>
<li><code>dest</code>: Destination directory on server where VM disk image will reside.</li>
</ol>
</li>
<li>
    If your VM is created successfully, there&#8217;ll be a config file for the VM in <code>/etc/libvirt/qemu/</code> (e.g. <code>/etc/libvirt/qemu/billiejean.xml</code>), and a disk image in the directory specified in the <code>--dest</code> option (e.g. <code>/root/vm-billiejean/disk0.qcow2</code>).
  </li>
<li>
    You can verify that it works by starting the VM and SSHing into it (virsh console will not work yet).</p>
<pre><code>virsh start billiejean</code></pre>
</li>
</ol>
<h3>Converting Disk Images to LVM Logical Volumes</h3>
<p>Now, we have the VM setup but it&#8217;s running off a disk image. For better performance, running the VM off a LVM logical volume will optimize disk IO.</p>
<p>vmbuilder is supposed to support the <code>--raw</code> option to write the VM to a block device (such as a LVM logical volume), but I&#8217;ve had no success with it (as does Mark Imbriaco, sysadmin of 37signals: <a href="http://twitter.com/markimbriaco/status/7437688341">http://twitter.com/markimbriaco/status/7437688341</a> and <a href="http://twitter.com/markimbriaco/status/7437699338">http://twitter.com/markimbriaco/status/7437699338</a>). We&#8217;re going to convert the disk images using qemu-img and write the bits into a LVM logical volume instead.</p>
<ol>
<li>Stop the VM if it&#8217;s running:
<pre><code>virsh shutdown billiejean</code></pre>
</li>
<li>Convert the VM&#8217;s qcow2 (QEMU image format) disk image to a raw disk image:
<pre><code>qemu-img convert disk0.qcow2 -O raw disk0.raw</code></pre>
</li>
<li>Create a logical volume to house the VM, making sure it&#8217;s big enough for the VM&#8217;s rootsize and swapsize options:
<pre><code>lvcreate -L24GB -n &lt;logical_volume_name&gt; &lt;volume_group_name&gt;</code></pre>
</li>
<li>Copy raw image into the logical volume:
<pre><code>dd if=disk0.raw of=/dev/&lt;volume_group_name&gt;/&lt;logical_volume_name&gt; bs=1M</code></pre>
<p>      This will take awhile (the bigger your image, the longer it takes).</li>
<li>Edit the VM&#8217;s config so that it uses your new logical volume:
<pre><code>virsh edit billiejean</code></pre>
<p>    Change <code>&lt;disk&gt;</code> to point to the logical volume:</p>
<pre><code>&lt;disk type='block' device='disk'&gt;
  &lt;source dev='/dev/&lt;volume_group_name&gt;/&lt;logical_volume_name&gt;'/&gt;
  &lt;target dev='hda' bus='ide'/&gt;
&lt;/disk&gt;</code></pre>
</li>
<li>Startup the VM. You might wanna rename the original <code>disk0.qcow2</code> image first just to make sure your VM isn&#8217;t still using it.</li>
<li>Once you&#8217;re sure your VM is running off your LVM logical volume, you can delete or backup the original qcow2 disk image.</li>
</ol>
<h3>Getting a console to your VM from the Host Server</h3>
<p>Now, we have to setup the VM so that virsh console works. This is a console to the VM from the host server that works even when the networking in the VM is not.</p>
<ol>
<li>Edit the VM&#8217;s settings:
<pre><code>virsh edit billiejean</code></pre>
<p>    In the <code>&lt;devices&gt;</code> block, add:</p>
<pre><code>&lt;serial type='pty'&gt;
  &lt;target port='0'/&gt;
&lt;/serial&gt;</code></pre>
</li>
<li>Startup your VM:
<pre><code>virsh start billiejean</code></pre>
</li>
<li>SSH into VM and create a file <code>/etc/init/ttyS0.conf</code>:
<pre><code>start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -8 38400 ttyS0 vt102</code></pre>
<p>      Start the tty with:</p>
<pre><code>start ttyS0</code></pre>
</li>
<li>Still in the VM, install acpid so that the VM will respond to shutdown commands from the server:
<pre><code>aptitude install acpid</code></pre>
</li>
<li>Reboot the VM.</li>
<li>Verify the console works by opening a console to the VM from the server:
<pre><code>virsh console billiejean</code></pre>
<p>      You may have to hit &#8220;Enter&#8221; before you see any console output.
  </li>
</ol>
<h3>Miscellaneous VM Setup</h3>
<p>That&#8217;s it, your VM is ready! You&#8217;ll probably want to do these:</p>
<ul>
<li>Set a root password and possibly delete the user you setup using <code>vmbuilder</code>.</li>
<li>Set the timezone with <code>dpkg-reconfigure tzdata</code>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2010/02/01/setting-up-virtualization-on-ubuntu-with-kvm/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A curl-ier Curb &#8211; better cookie support in Curb</title>
		<link>http://blog.codefront.net/2009/06/18/better-cookie-support-in-curb/</link>
		<comments>http://blog.codefront.net/2009/06/18/better-cookie-support-in-curb/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 01:42:10 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1144</guid>
		<description><![CDATA[As of Curb 0.3.7, Curb comes with slightly better cookie support that makes it more &#8220;curl-like&#8221;. It probably sounds like shameless self-promotion that I&#8217;m blogging about these changes since I&#8217;d contributed them. Well, yeah that&#8217;s true, but I&#8217;m also doing so because I doubt these changes will ever be made known since Curb doesn&#8217;t publicize [...]]]></description>
			<content:encoded><![CDATA[<p>As of <a href="http://github.com/taf2/curb/tree/master">Curb</a> 0.3.7, Curb comes with slightly better cookie support that makes it more &#8220;<a href="http://curl.haxx.se/">curl</a>-like&#8221;.</p>
<p>It probably sounds like shameless self-promotion that I&#8217;m blogging about these changes since I&#8217;d contributed them. Well, yeah that&#8217;s true, but I&#8217;m also doing so because I doubt these changes will ever be made known since Curb doesn&#8217;t publicize any updates or changelogs. </p>
<p>Curb is my current number 1 HTTP client for Ruby so the more love it gets, the better.</p>
<h3>Passing cookies as a string in Curb requests</h3>
<p>Curl veterans will probably know how to do this with the curl binary:</p>
<pre><code>curl -b "auth=abcdef; ASP.NET_SessionId=lotsatext;" example.com</code></pre>
<p>This sends a request to example.com with 2 cookies named &#8220;auth&#8221; and &#8220;ASP.NET_SessionId&#8221; (I hate those big-ass ASP.NET cookies btw). There wasn&#8217;t a way to set this in Curb, so I looked up the <a href="http://curl.haxx.se/libcurl/c/">libcurl C API docs</a> and replicated the same option in Curb (<a href="http://github.com/taf2/curb/commit/3c3e53c64a2417f78aa19f593a5f66e3ddffc969">commit on Github</a>). An example:</p>
<pre><code class="ruby">curl = Curl::Easy.new('http://example.com/')
curl.cookies = 'auth=abcdef; ASP.NET_SessionId=big-wall-of-text;'
curl.perform</code></pre>
<p>Of course, the cookies will more often be retrieved/constructed rather than a literal like in the example above. In my case, I was proxying cookies while trying to wrap an API around a site that doesn&#8217;t have one.</p>
<h3>Passing cookies as a file via the &#8220;cookiefile&#8221; option</h3>
<p>The second change is the new <code>cookiefile</code> option. This replicates curl commands like these:</p>
<pre><code>curl -b cookies-to-send.txt www.example.com</code></pre>
<p>with something like this in ruby:</p>
<pre><code class="ruby">curl = Curl::Easy.new('http://example.com/')
curl.cookiefile = '/path/to/cookies-to-send.txt'
curl.perform</code></pre>
<p>The cookies file looks like this (you can get a sample with the <code>--cookie-jar</code> option to curl, e.g. <code>curl --cookie-jar cookies.txt www.wego.com</code>):</p>
<pre><code>www.wego.com	FALSE	/	FALSE	0	lang
www.wego.com	FALSE	/	FALSE	0	user_country_code	SG</code></pre>
<p>Check out the <a href="http://github.com/taf2/curb/commit/a4910c25198441796f8e6d1958e144998833c7ec">commit on Github</a> if you&#8217;re interested.</p>
<h3>Why would I use these?</h3>
<p>Now you might be wondering how these 2 changes are useful &#8211; well, they <em>are</em> totally irrelevant to you if you&#8217;re not expecting any cookie support in Curb. However, if you&#8217;re accessing or scraping a site that uses <strong>cookie-based authentication</strong>, these changes allow you to keep your Curb client authenticated across sessions, even when doing HTTP POSTs (Curb doesn&#8217;t send cookies properly in POST requests even if <code>curl.enable_cookies</code> is set).</p>
<p>I&#8217;ve found these changes to Curb particularly useful since I vastly prefer Curb to most HTTP clients for its speed and lightweight implementation, and heavier scraper-type HTTP clients like <a href="http://mechanize.rubyforge.org/mechanize/">Mechanize</a> are a last resort.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2009/06/18/better-cookie-support-in-curb/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Living on the Edge (of Rails) has a new home at the Official Ruby on Rails weblog</title>
		<link>http://blog.codefront.net/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/</link>
		<comments>http://blog.codefront.net/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 09:55:39 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1123</guid>
		<description><![CDATA[You may have heard of it, but just in case, Living on the Edge is now going to be published on the official Ruby on Rails weblog. Big thanks to Gregg Pollack for getting me the new &#8220;gig&#8221;, and more importantly, for reviving and freshening up the content on the official Rails blog. Catch the [...]]]></description>
			<content:encoded><![CDATA[<p>You may have <a href="http://weblog.rubyonrails.org/2008/6/10/two-new-weekly-columns">heard of it</a>, but just in case, <a href="http://blog.codefront.net/category/edge-rails/">Living on the Edge</a> is now going to be published on the <a href="http://weblog.rubyonrails.org/">official Ruby on Rails weblog</a>. Big thanks to <a href="http://railsenvy.com/">Gregg Pollack</a> for getting me the new &#8220;gig&#8221;, and more importantly, for reviving and freshening up the content on the official Rails blog.</p>
<p>Catch the new first edition &#8211; this one&#8217;s about the <a href="http://weblog.rubyonrails.org/2008/6/20/living-on-the-edge-or-what-s-new-in-edge-rails-1-api-changes-and-performancetests">API changes since Rails 2.1</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/06/22/living-on-the-edge-of-rails-has-a-new-home-at-the-official-ruby-on-rails-weblog/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #22 &#8211; pre-Railsconf 2008 edition</title>
		<link>http://blog.codefront.net/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/</link>
		<comments>http://blog.codefront.net/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/#comments</comments>
		<pubDate>Sun, 25 May 2008 11:06:36 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1110</guid>
		<description><![CDATA[No mind-blowing changes in Rails this week prior to RailsConf &#8211; as Gregg mentioned last week in the Rails Envy podcast, it&#8217;s pre-2.1 days (Rails 2.1 will probably be released at RailsConf) so it&#8217;s pretty easy to see why. Oh and all Rails tests now pass in Ruby 1.9 after a long-standing #module_eval bug got [...]]]></description>
			<content:encoded><![CDATA[<p>No mind-blowing changes in Rails this week prior to RailsConf &#8211; as Gregg mentioned last week in the <a href="http://railsenvy.com/2008/5/21/rails-envy-podcast-episode-032">Rails Envy podcast</a>, it&#8217;s pre-2.1 days (Rails 2.1 will <em>probably</em> be released at RailsConf) so it&#8217;s pretty easy to see why. Oh and all Rails tests now pass in Ruby 1.9 after a long-standing <code>#module_eval</code> bug got fixed in Ruby 1.9&#8242;s trunk (see <a href="http://groups.google.com/group/ruby-core-google/browse_thread/thread/6d08e11363bf49b4">thread</a> for more details).</p>
<p>I&#8217;ll be at (my first) Railsconf 2008 in Portland, Oregon this Thursday onwards &#8211; if anyone sees me and recognizes me from my <a href="http://www.facebook.com/people/Chu_Yeow/500115784">Facebook picture</a> please come and say hi (no head butting though).</p>
<p>This week’s report covers changes from 19th May 2008 to 25th May 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>first and last methods now work with associations and named_scope</h3>
<p>Remember how the <a href="http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/">merging of the has_finder gem into Rails</a> allowed you to do things like <code>Post.first</code> and <code>Post.last</code>?</p>
<p>Now you can go one step further and use the same methods on your ActiveRecord associations. For example:</p>
<pre><code class="ruby">post = Post.find(1)
first_comment = post.comments.first</code></pre>
<p>If you have a <a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality">named_scope</a> named <code>recent</code> defined, you can even do this:</p>
<pre><code class="ruby">post.comments.recent.last</code></pre>
<p>This neat little enhancement is courtesy of <a href="http://railscasts.com/">Ryan Bates</a> (yes, that <em>Ryan Bates</em> of <a href="http://railscasts.com/">Railscasts</a> fame).</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/73c59638549686fccc749ffd3ac53cb533c5fd61">http://github.com/rails/rails/commit/73c59638549686fccc749ffd3ac53cb533c5fd61</a></p>
<h3>Cache stores now have an exist? method and controllers get fragment_exist?</h3>
<p>The cache stores in Rails (Memcache, file stores, etc.) now have an <code>exist?</code> method that checks whether a cached value exists given a cache key. This allows Rails controllers to expose a <code>fragment_exist?<br />
</code> method that allows you to check for existence of a cache fragment:</p>
<pre><code class="ruby">fragment_exist?('example.com/foo/bar')</code></pre>
<p>This little enhancement is courtesy of <a href="http://josevalim.blogspot.com/">José Valim</a>.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/99860b72aebe0348f41e82d4710343498d89a84b#diff-2">http://github.com/rails/rails/commit/99860b72aebe0348f41e82d4710343498d89a84b#diff-2</a></p>
<h3>Create association records with block argument</h3>
<p>You can now create records for associations like so:</p>
<pre><code class="ruby">post.coments.create!(:title => 'Techcrunch') do |c|
  c.body = "Rails can't scale"
end</code></pre>
<p>This is in keeping with the <a href="http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/">ActiveRecord::Base.create change previously mentioned</a>.</p>
<p>Credit for this patch goes (once again) to <a href="http://railscasts.com/">Ryan Bates</a>.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/6cba97d2a449faf21aec9fe9d4434067e414226f">http://github.com/rails/rails/commit/6cba97d2a449faf21aec9fe9d4434067e414226f</a></p>
<p>As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/05/25/living-on-the-edge-of-rails-22-pre-railsconf-2008-edition/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #21</title>
		<link>http://blog.codefront.net/2008/05/18/living-on-the-edge-of-rails-21/</link>
		<comments>http://blog.codefront.net/2008/05/18/living-on-the-edge-of-rails-21/#comments</comments>
		<pubDate>Sun, 18 May 2008 11:54:42 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1108</guid>
		<description><![CDATA[It&#8217;s another slow week (just 2 changes of note imho) after the release of the 1st Release Candidate (RC1) of Rails 2.1. Follow that link for installation instructions &#8211; though if you&#8217;re reading this blog post you probably don&#8217;t care! (because you&#8217;re, you know, &#8220;living on the edge&#8221;). Cheesiness aside, be sure to report any [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s another slow week (just 2 changes of note <acronym title="in my humble opinion">imho</acronym>) after the <a href="http://www.rubyinside.com/rails-21-released-891.html">release of the 1st Release Candidate (RC1) of Rails 2.1</a>. Follow that link for installation instructions &#8211; though if you&#8217;re reading this blog post you probably don&#8217;t care! (because you&#8217;re, you know, &#8220;living on the edge&#8221;). Cheesiness aside, be sure to report any bugs you may encounter when upgrading to 2.1 RC1 or edge at the <a href="http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/overview">Rails bug tracker</a> &#8211; it is an RC so any bug reports would be very welcome and useful!</p>
<p>This week’s report covers changes from 12th May 2008 to 18th May 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>caches_action can has conditionals</h3>
<p><code>caches_action</code> now takes an <code>:if</code> option (just like <a href="http://blog.codefront.net/2008/04/20/living-on-the-edge-of-rails-17/">caches_page does</a>). For example:</p>
<pre><code class="ruby">caches_action :index, :if =&gt; Proc.new { |c| !c.request.format.json? }</code></pre>
<p>This little enhancement is courtesy of José Valim.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/7708650f73ddb4db300ea2059c60c1d907a4384e">http://github.com/rails/rails/commit/7708650f73ddb4db300ea2059c60c1d907a4384e</a></p>
<h3>Bugfix: :select option is now scanned in ActiveRecord finders to ensure needed tables are included in generated SQL</h3>
<pre><code class="ruby">Post.find(:all, :include =&gt; :author, :select =&gt; 'posts.*, authors.id as "author_id"', :limit =&gt; 2)</code></pre>
<p>Would generate an SQL statement like this:</p>
<pre><code class="sql">SELECT posts.*, authors.id as "author_id" FROM "posts" LIMIT 2</code></pre>
<p>Notice how the <code>authors</code> table is not joined. This oversight is now fixed.</p>
<p>Thanks go to John Devine for this bugfix.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/b28b54cab090bed8f099ef375b419a8f92390dd4">http://github.com/rails/rails/commit/b28b54cab090bed8f099ef375b419a8f92390dd4</a></p>
<p>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!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/05/18/living-on-the-edge-of-rails-21/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #19 &#8211; change_table for migrations and more</title>
		<link>http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/</link>
		<comments>http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/#comments</comments>
		<pubDate>Sun, 04 May 2008 12:18:54 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1105</guid>
		<description><![CDATA[This week’s report covers changes from 29 April 2008 to 4th May 2008 (the day the corresponding Rails Envy podcast was recorded). change_table for ActiveRecord migrations Thanks to Jeff Dean, who also blogged about the new change_table feature in ActiveRecord migrations, you can now change a table with a block like so: change_table :videos do [...]]]></description>
			<content:encoded><![CDATA[<p>This week’s report covers changes from 29 April 2008 to 4th May 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>change_table for ActiveRecord migrations</h3>
<p>Thanks to <a href="http://zilkey.com/">Jeff Dean</a>, who also <a href="http://zilkey.com/2008/4/29/new-rails-core-feature-proposal-super-sexy-migrations">blogged about the new change_table feature in ActiveRecord migrations</a>, you can now change a table with a block like so:</p>
<pre><code class="ruby">change_table :videos do |t|
  t.add_timestamps
  t.add_belongs_to :goat
  t.add_string :name, :email, :limit =&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</code></pre>
<p>Some key things to note:</p>
<ul>
<li><code>add_XXX</code> would add a new column for you, e.g. <code>add_string</code> would add a new string field.</li>
<li>Of course, add_timestamps would add the magic <code>created_at</code> and <code>updated_at</code> datetime fields.</li>
<li><code>remove_column</code> now takes multiple arguments.</li>
<li><code>rename</code> would rename the table.</li>
</ul>
<p>Very nice, DRY enhancement, props to <a href="http://zilkey.com/">Jeff Dean</a> once again.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/96980bd561d79824b6cb6efbcbecdcbf8785d452">http://github.com/rails/rails/commit/96980bd561d79824b6cb6efbcbecdcbf8785d452</a></p>
<h3>ActiveRecord::Base.create takes a block like ActiveRecord::Base.new</h3>
<p>Yup now you can also <code>create</code> ActiveRecord objects with a block argument just like you could for <code>ActiveRecord::Base.new</code>:</p>
<pre><code class="ruby">@person = Person.create(params[:person]) do |p|
  p.name = 'Konata Izumi'
  p.age = 17
end</code></pre>
<p>Credit goes to <a href="http://www.workingwithrails.com/person/11022-adam-meehan">Adam Meehan</a> for this patch.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/dd120ede53eaf71dee76894998a81626b7a689fc">http://github.com/rails/rails/commit/dd120ede53eaf71dee76894998a81626b7a689fc</a></p>
<h3>Bugfix: change_column should be able to use :null => true on a field that<br />
formerly had false</h3>
<p>You can now use <code>change_column</code> in your migrations to alter a column as nullable if it was previously <code>NOT NULL</code>.</p>
<p>This bugfix is courtesy of Nate Wiger.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/10ef65a3b054270ed3d458ec8eb7c2b9a3e638f7">http://github.com/rails/rails/commit/10ef65a3b054270ed3d458ec8eb7c2b9a3e638f7</a></p>
<p>As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/05/04/living-on-the-edge-of-rails-19-change_table-for-migrations-and-more/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #18</title>
		<link>http://blog.codefront.net/2008/04/27/living-on-the-edge-of-rails-18/</link>
		<comments>http://blog.codefront.net/2008/04/27/living-on-the-edge-of-rails-18/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 11:18:36 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1102</guid>
		<description><![CDATA[This week’s report covers changes from 21 Apr 2008 to 27 Apr 2008 (the day the corresponding Rails Envy podcast was recorded). Not much interesting to report this week &#8211; there were mostly a bunch of bugfixes and Ruby 1.8.7-compatibility commits. Introduce ActiveResource::Base.timeout and rescuing from Timeout::Error in ActiveResource::Connection These are 2 changes that I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>This week’s report covers changes from 21 Apr 2008 to 27 Apr 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<p>Not much interesting to report this week &#8211; there were mostly a bunch of bugfixes and Ruby 1.8.7-compatibility <a href="http://github.com/rails/rails/commits/master">commits</a>.</p>
<h3>Introduce ActiveResource::Base.timeout and rescuing from Timeout::Error in ActiveResource::Connection</h3>
<p>These are <a href="http://github.com/rails/rails/commit/105910429d5873dce677ef32eef5f705e0625d86">2</a> <a href="http://github.com/rails/rails/commit/cf32baf915442ffe153ec0e4d8148f147776c30a">changes</a> that I&#8217;d <a href="http://blog.codefront.net/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/">talked about</a> earlier this week so I won&#8217;t repeat myself &#8211; take a read through <a href="http://blog.codefront.net/2008/04/22/new-in-rails-activeresource-timeouts-and-why-it-matters/">ActiveResource timeouts and why it matters</a>.</p>
<h3>Smart integer datatype for the MySQL adapter in migrations</h3>
<p>The MySQL adapter in Rails now maps the <code>integer</code> column type in your migrations to either smallint, int, or bigint depending on the :limit option.</p>
<p>This means that a migration like this:</p>
<pre><code class="ruby">def self.up
  create_table :searches do |t|
    t.integer :foo, :limit => 2
  end</code></pre>
<p>will create your <code>foo</code> column as a <code>smallint(2)</code> MySQL datatype (instead of <code>int(2)</code> before). (More information <a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html">MySQL numeric datatypes</a>.)</p>
<p>Credit goes to DHH for this patch.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/a37546517dad9f6d9a7de6e1dba4d960909d71e8">http://github.com/rails/rails/commit/a37546517dad9f6d9a7de6e1dba4d960909d71e8</a></p>
<p>As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/04/27/living-on-the-edge-of-rails-18/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #17</title>
		<link>http://blog.codefront.net/2008/04/20/living-on-the-edge-of-rails-17/</link>
		<comments>http://blog.codefront.net/2008/04/20/living-on-the-edge-of-rails-17/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 11:21:22 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1099</guid>
		<description><![CDATA[Not much going on this week on edge Rails. It does seem however that we do have a new Rails core member, Joshua Peek. Also, the new Rails&#8217; bug tracker hosted on Lighthouse is ready for use, so be sure to submit your patches and bug reports there. This week’s report covers changes from 14 [...]]]></description>
			<content:encoded><![CDATA[<p>Not much going on this week on edge Rails. It does seem however that we do have a new Rails core member, <a href="http://joshpeek.com/">Joshua Peek</a>. Also, the new <a href="http://rails.lighthouseapp.com/">Rails&#8217; bug tracker</a> hosted on Lighthouse is ready for use, so be sure to submit your patches and bug reports there.</p>
<p>This week’s report covers changes from 14 Apr 2008 to 20 Apr 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>Conditional caches_page</h3>
<p>The <code>caches_page</code> now takes an <code>:if</code> option for specifying when a page can actually be cached via a Proc. You can now do this, for example:</p>
<pre><code class="ruby">caches_page :index, :if =&gt; Proc.new { |c| !c.request.format.json? }</code></pre>
<p>That will only cache your index page if the requested format is not JSON.</p>
<p>Credit goes to <a href="http://deaddeadgood.com/">Paul Horsfall</a> for this enhancement.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/14a40804a29a57ad05ca6bffbe1e5334089593a9">http://github.com/rails/rails/commit/14a40804a29a57ad05ca6bffbe1e5334089593a9</a></p>
<h3>New ActionView::TestCase for testing view helpers</h3>
<p>Remember how you can now use <a href="http://blog.codefront.net/2007/12/27/dry-in-your-functional-and-actionmailer-tests-rails-20-a-feature-a-day-7/">specialized TestCase classes for testing controllers and ActionMailer classes</a>? Now you can do the same with your Rails view helpers with the new ActionView::TestCase class.</p>
<p>Here&#8217;s a quick example:</p>
<pre><code class="ruby">module PeopleHelper
  def title(text)
    content_tag(:h1, text)
  end

  def homepage_path
    people_path
  end
end

class PeopleHelperTest &lt; ActionView::TestCase
def setup
  ActionController::Routing::Routes.draw do |map|
    map.people 'people', :controller =&gt; 'people', :action =&gt; 'index'
    map.connect ':controller/:action/:id'
  end
end

def test_title
  assert_equal "&lt;h1&gt;Ruby on Rails&lt;/h1&gt;", title("Ruby on Rails")
end

def test_homepage_path
  assert_equal "/people", homepage_path
end</code></pre>
<p>Credit goes to Josh Peek for this sweet little enhancement.</p>
<h3>ActiveSupport::Cache&#8217;s mem_cache_store accepts options</h3>
<p>Even though Memcache-client was added to ActiveSupport recently, it didn&#8217;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:</p>
<pre><code class="ruby">config.action_controller.fragment_cache_store = :mem_cache_store, 'localhost', { :compression =&gt; true, :debug =&gt; true, :namespace =&gt; 'foo' }</code></pre>
<p>This patch is courtesy of <a href="http://blog.innerewut.de/">Jonathan Weiss</a>.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/9e1d506a8cfedef2fdd605e4cbf4bf53651ad214">http://github.com/rails/rails/commit/9e1d506a8cfedef2fdd605e4cbf4bf53651ad214</a></p>
<p>As always, let me know of any suggestions or how I can improve the Living on the Edge (of Rails) series.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/04/20/living-on-the-edge-of-rails-17/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #16 &#8211; Github edition</title>
		<link>http://blog.codefront.net/2008/04/13/living-on-the-edge-of-rails-16-github-edition/</link>
		<comments>http://blog.codefront.net/2008/04/13/living-on-the-edge-of-rails-16-github-edition/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 08:09:43 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1097</guid>
		<description><![CDATA[A slight change this week since Rails has moved to Git &#8211; all changesets are now referenced to Github. This week’s report covers changes from 7 Apr 2008 to 13 Apr 2008 (the day the corresponding Rails Envy podcast was recorded). A helpers proxy method for accessing helper methods from outside of views A helpers [...]]]></description>
			<content:encoded><![CDATA[<p>A slight change this week since <a href="http://weblog.rubyonrails.org/2008/4/11/rails-premieres-on-github">Rails has moved to Git</a> &#8211; all changesets are now referenced to <a href="http://github.com/rails/rails/tree/master">Github</a>.</p>
<p>This week’s report covers changes from 7 Apr 2008 to 13 Apr 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>A helpers proxy method for accessing helper methods from outside of views</h3>
<p>A <code>helpers</code> method has been introduced to ActionController &#8211; you can now access your helpers like so:</p>
<pre><code class="ruby">ApplicationController.helpers.simple_format(text)</code></pre>
<p>Credit goes to 19 year old <a href="http://joshpeek.com/">Josh Peek</a>, one of the more prolific Rails contributors (and most likely to join Pratik in Rails Core imo).</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/917423d664038d6791738a73ad1446437dbb71df">http://github.com/rails/rails/commit/917423d664038d6791738a73ad1446437dbb71df</a></p>
<h3>json_escape for escaping HTML entities in JSON strings</h3>
<p>A <code>json_escape</code> (aliased as <code>j</code>, similar to how <code>html_escape</code> is aliased as <code>h</code>) 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):</p>
<pre><code class="ruby">json_escape("is a &gt; 0 &amp; a &lt; 10?")
# => is a \u003E 0 \u0026 a \u003C 10?</code></pre>
<p>Of course, since <code>json_escape</code> is aliased as <code>j</code>, you can do this in your ERB templates:</p>
<pre><code class="ruby"><%=j @person.to_json %></code></pre>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/0ff7a2d89fc95dcb0a32ed92aab7156b0778a7ea">http://github.com/rails/rails/commit/0ff7a2d89fc95dcb0a32ed92aab7156b0778a7ea</a></p>
<h3>Automatically parse posted JSON content for Mime::JSON requests</h3>
<p>Rails will now accept POSTed JSON content! For example, you can now send a POST to &#8220;/posts&#8221; of your Post resource like this:</p>
<pre><code>POST /posts
{"post": {"title": "Breaking News"}}</code></pre>
<p>And your <code>create</code> action will automatically parse the POSTed JSON into the request <code>params</code> so that this code below just works:</p>
<pre><code class="ruby">def create
  @post = Post.create params[:post]
end</code></pre>
<p>Credit goes to Rick Olson.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/4d594cffcfc93b37fad4e423ec8593299e50133c">http://github.com/rails/rails/commit/4d594cffcfc93b37fad4e423ec8593299e50133c</a></p>
<h3>schema_migrations table replaces the schema_info table, allowing for interleaved migrations</h3>
<p>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&#8217;ve merged from someone&#8217;s branch) &#8211; when you migrate your database via rake db:migrate, those never-applied &#8220;interleaved&#8221; migrations will be run. Similarly, when migrating down schema versions, never-applied &#8220;interleaved&#8221; will be skipped.</p>
<p>See <a href="http://dev.rubyonrails.org/ticket/11493">http://dev.rubyonrails.org/ticket/11493</a> for more information.</p>
<p>This useful patch is the brainchild of <a href="http://bunster.org/">Jordi Bunster</a> (<a href="http://www.workingwithrails.com/person/12130-jordi-bunster">WWR profile</a>). I&#8217;m sure many Rails developers who branch extensively will thank Jordi for this excellent patch!</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e">http://github.com/rails/rails/commit/8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e</a></p>
<h3>gems:unpack:dependencies Rake task</h3>
<p>Remember how you can now run the <code>gems:unpack</code> Rake task to unpack a gem into your <code>vendor/gems/</code> directory (this was <a href="http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/">mentioned in an earlier Living on the Edge</a>)?</p>
<p>David Dollar (<a href="http://github.com/ddollar">Github profile</a>) has firmed up that patch quite a bit by adding the <code>gems:unpack:dependencies</code> Rake task that unpacks the dependencies of the gems as well. So running:</p>
<pre><code>gems:unpack:dependencies GEM=activecouch</code></pre>
<p>would unpack the full Rubygem dependency tree of gems that the <a href="http://code.google.com/p/activecouch/">activecouch</a> gem depends upon.</p>
<p>Related changeset: <a href="http://github.com/rails/rails/commit/4364c361b599f99bc2345ce4eb2d145b07ed8a0f">http://github.com/rails/rails/commit/4364c361b599f99bc2345ce4eb2d145b07ed8a0f</a></p>
<p>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 <a href="http://github.com/rails/rails/tree/master">forking Rails</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/04/13/living-on-the-edge-of-rails-16-github-edition/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #15 &#8211; the early edition</title>
		<link>http://blog.codefront.net/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/</link>
		<comments>http://blog.codefront.net/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 07:57:01 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/?p=1096</guid>
		<description><![CDATA[I&#8217;m gonna post up the Living on the Edge a little earlier this week because I&#8217;ve found I just can&#8217;t keep up (when things get busy) with 2 separate sets of notes for the Rails Envy podcast and another for my own blog posts. From this week onwards, I&#8217;ll be following Pratik&#8216;s suggestion to post [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m gonna post up the Living on the Edge a little earlier this week because I&#8217;ve found I just can&#8217;t keep up (when things get busy) with 2 separate sets of notes for the <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> and another for my own blog posts.</p>
<p>From this week onwards, I&#8217;ll be following <a href="http://m.onkey.org">Pratik</a>&#8216;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!</p>
<p>This week’s report covers changes from 31 Mar 2008 to 6 Apr 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>Rails.env, Rails.logger, Rails.cache, Rails.root</h3>
<p>This has been a long time coming: You can now use <code>Rails.env</code> instead of <code>RAILS_ENV</code>, <code>Rails.root</code> instead of <code>RAILS_ROOT</code>, <code>Rails.logger</code> instead of <code>RAILS_DEFAULT_LOGGER</code>, and <code>Rails.cache</code> instead of <code>RAILS_CACHE</code>. 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.</p>
<p>Credit goes to <a href="http://m.onkey.org/">Pratik Naik</a>, the newest Rails core team member for this cleanup.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9180">http://dev.rubyonrails.org/changeset/9180</a></p>
<h3>Render :partial now works with a collection of heterogeneous elements</h3>
<p>You can now use <code>render :partial</code> to render a collection of different elements and Rails will figure out which partial template to use. For example:</p>
<pre><code class="ruby">render :partial => [ monkey, donkey, dramatic_chipmunk ]</code></pre>
<p>will render the monkey with the &#8216;monkeys/_monkey.html.erb&#8217; partial, donkey with the &#8216;donkeys/_donkey.html.erb&#8217; partial, and last but definitely not lest, dramatic_gopher with the &#8216;dramatic_chipmunks/_dramatic_chipmunk.html.erb&#8217; partial</p>
<p>This is especially useful if when using <acronym title="Single Table Inheritance">STI</acronym>, where your ActiveRecord model would return objects of different types. The collection <code>[ monkey, donkey, dramatic_chipmunk ]</code> could very well be something returned from your <code>Animal</code> model that has subclasses of <code>Monkey</code>, <code>Donkey</code> and <code>DramaticChipmunk</code> via STI.</p>
<p>Credit: <a href="http://www.continuousthinking.com/">Zach Dennis</a> of <a href="http://www.continuousthinking.com/tags/arext">ar-extensions</a> fame.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9177">http://dev.rubyonrails.org/changeset/9177</a></p>
<h3>ActiveModel work revived</h3>
<p>It seems like work on ActiveModel (think unified ActiveRecord and ActiveResource behaviors) has been revived, if the latest commits (<a href="http://dev.rubyonrails.org/changeset/9171">http://dev.rubyonrails.org/changeset/9171</a> and <a href="http://dev.rubyonrails.org/changeset/9173">http://dev.rubyonrails.org/changeset/9173</a>) by David (DHH) is anything to go by.</p>
<h3>Bugfix: Assigning an invalid has_one association now causes #save to fail on parent</h3>
<p>You could do this before:</p>
<pre><code class="ruby">firm = Firm.find(:first)
firm.account = Account.new # Associate INVALID account
firm.save # This doesn't fail</code></pre>
<p>Now that&#8217;s fixed thanks to <a href="http://m.onkey.org/">Pratik Naik</a>.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9232">http://dev.rubyonrails.org/changeset/9232</a></p>
<p>As usual, any feedback is respectfully appreciated!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/04/06/living-on-the-edge-of-rails-15-the-early-edition/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #14 &#8211; the extreme edition. Extremely late.</title>
		<link>http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/</link>
		<comments>http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 16:04:06 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/</guid>
		<description><![CDATA[This week’s report covers changes from 24 Mar 2008 to 30 Mar 2008 (the day the corresponding Rails Envy podcast was recorded). There&#8217;re lots of big exciting changes this week on edge. Smells like 2.1 soon! has_finder gem merged into Rails Ryan Daigle has the scoop on the new has_finder-like functionality in Rails so head [...]]]></description>
			<content:encoded><![CDATA[<p>This week’s report covers changes from 24 Mar 2008 to 30 Mar 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<p>There&#8217;re lots of big exciting changes this week on edge. Smells like 2.1 soon!</p>
<h3>has_finder gem merged into Rails</h3>
<p>Ryan Daigle has <a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality">the scoop on the new has_finder-like functionality in Rails</a> so head on over (I won&#8217;t repeat it here in the interests of <acronym title="Don't Repeat Yourself">DRY</acronym>).</p>
<p>Credit goes to <a href="http://pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries">Nick Kallen</a> for coming up with the has_finder gem.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9084">http://dev.rubyonrails.org/changeset/9084</a></p>
<h3>ActiveRecord: Unsaved attribute changes are now tracked</h3>
<p>You can now ask an ActiveRecord model whether its attributes have been changed (and is unsaved) using the <code>{attr_name}_changed?</code> (magic) method. The <code>{attr_name}_was</code> method will return the original value of the attribute, and the <code>{attr_name}_change</code> method will return an array with 2 members, the 1st being the original value, the 2nd being the changed (and unsaved) value.</p>
<pre><code class="ruby"># Change person's name.
person.name = 'Jason Seifer'
person.changed?       # => true
person.name_changed?  # => true
person.name_was       # => 'jseifer'
person.name_change    # => ['jseifer', 'Jason Seifer']
person.name = 'Ceiling Cat'
person.name_change    # => ['jseifer', 'Ceiling Cat']</code></pre>
<p>Credit goes to Rails core team member Jeremy Kemper (bitsweat) for this patch (which originated from Jeremy&#8217;s very own <a href="http://code.bitsweat.net/svn/dirty">Dirty plugin</a>).</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9127">http://dev.rubyonrails.org/changeset/9127</a></p>
<h3>ActiveRecord#Base.all/first/last</h3>
<p>Now you can do:</p>
<pre><code class="ruby">Post.all.each { |post| # something }
Post.first
Post.last</code></pre>
<p>Kinda like how some other ORMs do (like DataMapper).</p>
<p>Credit: <a href="http://www.thechrisoshow.com/">thechrisoshow</a> and again, Nick Kallen for has_finder.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9085">http://dev.rubyonrails.org/changeset/9085</a></p>
<h3>Timestamped Migrations</h3>
<p>This is more useful than it sounds: migrations are now timestamped instead of using incremental numbers in your db/migrate folder. This eliminates the problem of migrations having the same version number when working on a multi-developer Rails app.</p>
<p>Two new Rake tasks, rake <code>db:migrate:up/down</code>, have been added to allow running of the <code>up</code> and <code>down</code> methods of individual migrations.</p>
<p>Credit goes to John Barnette, the guy who gave you <a href="http://ryandaigle.com/articles/2007/10/26/what-s-new-in-edge-rails-fixtures-just-got-a-whole-lot-easier">foxy fixtures</a>.</p>
<p>Related changeset:<a href=" http://dev.rubyonrails.org/changeset/9122"> http://dev.rubyonrails.org/changeset/9122</a></p>
<h3>New config.gem option for specifying which gems are required by the application + rake tasks for installing and freezing gems</h3>
<p>Specify which gems are required by your Rails app in your Rails <code>environment.rb</code>! &#8220;Vendor everything&#8221; supported right in Rails :). An example:</p>
<pre><code class="ruby">Rails::Initializer.run do |config|
  config.gems 'chronic'
  config.gems "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
  config.gems "aws-s3", :lib => "aws/s3"
end</code></pre>
<p>There are also new Rake tasks:</p>
<pre><code class="ruby"># List required gems.
rake gems 

# Install all required gems:
rake gems:install 

# Unpack specified gem to vendor/gems/gem_name-x.x.x
rake gems:unpack GEM=chronic</code></pre>
<p>Credit goes to the prolific <a href="http://techno-weenie.net/">Rick Olson</a> for this gem of a patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9140">http://dev.rubyonrails.org/changeset/9140</a></p>
<h3>ActiveResource #clone</h3>
<p>You can now clone an existing resource:</p>
<pre><code class="ruby">gregg = Person.find(1)
borg = gregg.clone</code></pre>
<p>This doesn&#8217;t clone child ActiveResource members though, just the straight up attributes of resource.</p>
<p>Contribors: <a href="http://ryandaigle.com/">Ryan Daigle</a> and <a href="http://www.thechrisoshow.com/">thechrisoshow</a>.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9121">http://dev.rubyonrails.org/changeset/9121</a></p>
<h3>Big documentation patch</h3>
<p>A big doc patch consisting of all the efforts going on in the <a href="http://github.com/lifo/doc-rails/">doc-rails repository on Github</a> has been committed. Check out <a href="http://groups.google.com/group/rubyonrails-core/browse_thread/thread/92f822141df3c217/71e7460d41bdfd89">Pratik&#8217;s post</a> for more info on what doc-rails is. Though with Rails moving to Git soon, doc-rails may no longer be necessary!</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9093">http://dev.rubyonrails.org/changeset/9093</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/04/05/living-on-the-edge-of-rails-14-the-extreme-edition-extremely-late/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #13 &#8211; Git script/plugin install, has_one :through</title>
		<link>http://blog.codefront.net/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/</link>
		<comments>http://blog.codefront.net/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 15:46:34 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/</guid>
		<description><![CDATA[It&#8217;s time again for some edge Rails love. If you haven&#8217;t listened to it yet, be sure to check out this week&#8217;s Rails Envy podcast This week’s report covers changes from 17 Mar 2008 to 23 Mar 2008 (the day the corresponding Rails Envy podcast was recorded). script/plugin install works for Git repositories Yup you [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s time again for some edge Rails love. If you haven&#8217;t listened to it yet, be sure to check out <a href="http://railsenvy.com/2008/3/26/rails-envy-podcast-episode-024-03-26-2008">this week&#8217;s Rails Envy podcast</a></p>
<p>This week’s report covers changes from 17 Mar 2008 to 23 Mar 2008 (the day the <a href="http://railsenvy.com/2008/3/26/rails-envy-podcast-episode-024-03-26-2008">corresponding Rails Envy podcast</a> was recorded).</p>
<h3>script/plugin install works for Git repositories</h3>
<p>Yup you can now install plugins from <a href="http://git.or.cz/">Git</a> repositories simply by running:</p>
<p><code>script/plugin install git://github.com/foo/kung_fu</code></p>
<p>What this really does is to clone a git repository (sans the entire git history by passing the <code>—depth 1</code> option) into your plugins directory. If you&#8217;re looking for a Piston-like way to manage external Git repositories though, you&#8217;d still be better off with the development version of <a href="http://piston.rubyforge.org/">Piston</a> (François Beausoleil, is <a href="http://blog.teksol.info/tags/piston">posting frequently on his progress with adding Git support</a>).</p>
<p>Credit goes to <a href="http://6brand.com/git-svn-externals-rails-plugins">Jack Danger</a>, a long-time Rails contributor for this patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9049">http://dev.rubyonrails.org/changeset/9049</a></p>
<h3>has_one :through</h3>
<p>It&#8217;s been a long time coming &#8211; now you can do <code>has_one :through</code> (like <code>has_many :through</code>) for your join models. <a href="http://ryandaigle.com/">Ryan Daigle</a> has <a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-one-through">example code</a> on how to use it if you&#8217;re curious (though really, it&#8217;s just like has_many).</p>
<p>Credit goes to the <a href="http://artofmission.com/">Art of Mission</a> guys and <a href="http://www.thechrisoshow.com/ http://www.workingwithrails.com/person/9008-chris-o-sullivan">Chris O&#8217;Sullivan</a> for pulling it all together.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9067">http://dev.rubyonrails.org/changeset/9067</a></p>
<h3>rake tasks time:zones:all, time:zones:us and time:zones:local</h3>
<p>Some timezone-related rake tasks have been added to list the names of time zones recognized by the <code>TimeZone</code> class for the <code>config.time_zone</code> option you can put in your <code>environment.rb</code>. For example</p>
<p><code>rake time:zones:local</code></p>
<pre><code>* UTC +08:00 *
Beijing
Chongqing
Hong Kong
Irkutsk
Kuala Lumpur
Perth
Singapore
Taipei
Ulaan Bataar
Urumqi</code></pre>
<p>Credit: Geoff Buesing (core team member)</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9074">http://dev.rubyonrails.org/changeset/9074</a></p>
<h3>#number_to_currency helper now supports a :format option</h3>
<p>Now you can do something like:</p>
<pre><code class="ruby">number_to_currency(123.50, :unit => "&pound;", :format => "%n %u")
# => 123.50 &pound;</code></pre>
<p>Instead of being stuck with the <code>{currency_code} {amount}</code> format which doesn&#8217;t work in some locales (such as &#8220;42 pounds&#8221;).</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9052">http://dev.rubyonrails.org/changeset/9052</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/03/27/living-on-the-edge-of-rails-13-git-scriptplugin-install-has_one-through/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #12</title>
		<link>http://blog.codefront.net/2008/03/20/living-on-the-edge-of-rails-12/</link>
		<comments>http://blog.codefront.net/2008/03/20/living-on-the-edge-of-rails-12/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 12:19:18 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/2008/03/20/living-on-the-edge-of-rails-12/</guid>
		<description><![CDATA[This week’s report covers changes from 10 Mar 2008 to 16 Mar 2008 (the day the corresponding Rails Envy podcast was recorded). Custom JavaScript and stylesheet symbols Remember how you can do something like: javascript_include_tag :defaults and Rails would load all the Prototype JavaScript files and your application.js? You can now register your own custom [...]]]></description>
			<content:encoded><![CDATA[<p>This week’s report covers changes from 10 Mar 2008 to 16 Mar 2008 (the day the <a href="http://railsenvy.com/2008/3/19/rails-envy-podcast-episode-023-03-19-2008">corresponding Rails Envy podcast</a> was recorded).</p>
<h3>Custom JavaScript and stylesheet symbols</h3>
<p>Remember how you can do something like:</p>
<pre><code class="ruby">javascript_include_tag :defaults</code></pre>
<p>and Rails would load all the Prototype JavaScript files and your application.js?</p>
<p>You can now register your own custom expansion symbol too:</p>
<pre><code class="ruby"># In a Rails initializer.
ActionView::Helpers::AssetTagHelper.register_javascript_expansion :yui => ['yahoo', 'autocomplete', 'calendar']

# In your view.
javascript_include_tag :yui</code></pre>
<p>would result in:</p>
<pre><code class="html">&lt;script type="text/javascript" src="/javascripts/yahoo.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/javascripts/autocomplete.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/javascripts/calendar.js"&gt;&lt;/script&gt;</code></pre>
<p>You can do the same with the <cpde>stylesheet_link_tag</cpde> by registering a custom expansion symbol via <code>register_stylesheet_expansion</code>.</p>
<p>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.</p>
<p><strong>Warning</strong>: This patch currently breaks the default symbols like <code>:all</code> (<a href="http://dev.rubyonrails.org/ticket/10350">check out the ticket</a> for more info).</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9016">http://dev.rubyonrails.org/changeset/9016</a></p>
<h3>Sexy default timestamps in migrations</h3>
<p>Remember how you can say <code>timestamps</code> in a migration and Rails will create the &#8216;created_at&#8217; and &#8216;updated_at&#8217; columns for you? You can now also do <code>add_timestamps :table_name</code> and <code>remove_timestamps :table_name</code> in your migrations if you decide to add these columns later to a table:</p>
<pre><code class="ruby">def self.up
  add_timestamps :posts
end

def self.down
  remove_timestamps :posts
end</code></pre>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9014">http://dev.rubyonrails.org/changeset/9014</a></p>
<h3>ActiveRecord::Base#find(:last)</h3>
<p>Just like <code>Comment.find(:first)</code>, you can now do something like <code>Comment.find(:last)</code>. There&#8217;s some controversy over whether this is bloat, but <acronym title="David Heinemeier Hansson">DHH</acronym> makes a good case for it with this example:</p>
<pre><code class="ruby">class Person
  has_many :comments, :order =&gt; 'created_at'
end

@some_person.comments.find(:last) # =&gt; Returns the most recent comment.</code></pre>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9012">http://dev.rubyonrails.org/changeset/9012</a></p>
<h3>Database rake tasks fixes</h3>
<p><code>rake db:create</code> used to ignore the &#8216;charset&#8217; and &#8216;collation&#8217; options in your database.yml configuration file. This has been fixed so that your created databases now respect those options.</p>
<p><code>rake db:drop</code> and <code>rake db:migrate:reset</code> also no longer crash with an unhelpful exception if the database has already been dropped, and instead shows a proper error message.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9004">http://dev.rubyonrails.org/changeset/9004</a></p>
<h3>Rails&#8217; logger now creates the log directory if it doesn&#8217;t exist</h3>
<p>This is a blessing to those of us who use version control systems that don&#8217;t support empty directories (like Git). Rails&#8217; default logger (the BufferedLogger), now creates a log/ directory if it doesn&#8217;t already exist. This should save you the step of creating/symlinking a log/ directory (or symlinking) on deploy.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9013">http://dev.rubyonrails.org/changeset/9013</a></p>
<h3>String#squish is faster</h3>
<p>A faster implementation of the <code>String#squish</code> (and <code>String#squish!</code>) core extension has been committed.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9015">http://dev.rubyonrails.org/changeset/9015</a></p>
<h3>The #excerpt TextHelper no longer includes 1 character too many</h3>
<p>Turns out that the <code>#excerpt</code> helper method was consistently including an extra character. This has been fixed.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/9030">http://dev.rubyonrails.org/changeset/9030</a></p>
<p>As usual, let me know of any inaccuracies or any suggestions you may have in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/03/20/living-on-the-edge-of-rails-12/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #11</title>
		<link>http://blog.codefront.net/2008/03/12/living-on-the-edge-of-rails-11/</link>
		<comments>http://blog.codefront.net/2008/03/12/living-on-the-edge-of-rails-11/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 11:39:17 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/2008/03/12/living-on-the-edge-of-rails-11/</guid>
		<description><![CDATA[This week’s report covers changes from 3 Mar 2008 to 9 Mar 2008 (the day the corresponding Rails Envy podcast was recorded). Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query This is another ActiveRecord performance boost related to the pre-loading any eager-loaded :includes mentioned previously. Basically what this patch does is to [...]]]></description>
			<content:encoded><![CDATA[<p>This week’s report covers changes from 3 Mar 2008 to 9 Mar 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query</h3>
<p>This is another ActiveRecord performance boost related to the pre-loading any eager-loaded <code>:includes</code> <a href="http://blog.codefront.net/2008/01/30/living-on-the-edge-of-rails-5-better-eager-loading-and-more/">mentioned previously</a>. Basically what this patch does is to only join referenced tables when needed. It does this by checking the <code>:conditions</code> and <code>:limit</code> 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 <a href="http://dev.rubyonrails.org/ticket/9560">#9560</a> and <a href="http://dev.rubyonrails.org/ticket/9497">#9497</a>.</p>
<p>Credit goes to <a href="http://www.workingwithrails.com/person/8164-gabe-da-silveira"> Gabe da Silveira</a> (dasil003 on Trac) for this awesome performance patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8977">http://dev.rubyonrails.org/changeset/8977</a></p>
<h3>Better error message for type errors when parsing request parameters</h3>
<p>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.</p>
<p>Contributors: <a href="http://www.workingwithrails.com/person/5519-chad-humphries">Chad Humphries</a> and matt.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8986">http://dev.rubyonrails.org/changeset/8986</a></p>
<h3>Make MimeResponds::Responder#any work without explicit types.</h3>
<p>Here&#8217;s something I didn&#8217;t know: you can actually use <code>any</code> in your <code>respond_to</code> blocks as a catch-all response. E.g.</p>
<pre><code class="ruby">respond_to do |format|
  format.html do
    redirect_to :action =&gt; 'login'
  end
  format.any(:js, :xml) do
    request_http_basic_authentication 'Web Password'
  end
end</code></pre>
<p>Contrary to its name, using &#8216;any&#8217; actually requires you to pass a list of types to respond to. This has been enhanced now so that if you don&#8217;t pass any arguments, it&#8217;ll function as a real catch-all.</p>
<pre><code class="ruby">respond_to do |format|
  format.any do
    request_http_basic_authentication 'Web Password'
  end
end</code></pre>
<p>Credit goes to <a href="http://www.workingwithrails.com/person/3231-joshua-wehner">Joshua Wehner</a> for this patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8987">http://dev.rubyonrails.org/changeset/8987</a></p>
<h3>Add readonly option to has_many :through associations</h3>
<p>Turns out the <code>:readonly</code> option for associations <a href="http://blog.codefront.net/2008/02/19/living-on-the-edge-of-rails-8-the-code-optimization-edition/">mentioned earlier</a> was left out for <code>has_many :through</code> associations. This oversight has been fixed.</p>
<p>Thanks to <a href="http://www.workingwithrails.com/person/9147-emilio-tagua">Emilio Tagua</a> for this bugfix.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8989">http://dev.rubyonrails.org/changeset/8989</a></p>
<p>As usual, let me know of any inaccuracies or any suggestions you may have in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/03/12/living-on-the-edge-of-rails-11/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Living on the edge (of Rails) #10</title>
		<link>http://blog.codefront.net/2008/03/05/living-on-the-edge-of-rails-10/</link>
		<comments>http://blog.codefront.net/2008/03/05/living-on-the-edge-of-rails-10/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 12:01:32 +0000</pubDate>
		<dc:creator>Chu Yeow</dc:creator>
				<category><![CDATA[Edge Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.codefront.net/2008/03/05/living-on-the-edge-of-rails-10/</guid>
		<description><![CDATA[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 Rails Envy podcast, there has been some nice changes (that I&#8217;ll be mentioning next week, but there&#8217;s absolutely nothing stopping you from checking those out yourself). In other interesting [...]]]></description>
			<content:encoded><![CDATA[<p>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 <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a>, there has been some nice changes (that I&#8217;ll be mentioning next week, but there&#8217;s absolutely nothing stopping you from <a href="http://dev.rubyonrails.org/timeline?changeset=on">checking those out yourself</a>).</p>
<p>In other interesting news, <a href="http://m.onkey.org/">Pratik Naik</a> (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 <a href="http://m.onkey.org/">http://m.onkey.org/</a> (where he&#8217;s not afraid to say &#8220;fuck&#8221; in his posts <em>and</em> his code) and hangs out an awful lot on <a href="irc://irc.freenode.net/rubyonrails">#rubyonrails</a> and <a href="irc://irc.freenode.net/rails-contrib">#rails-contrib</a> on IRC.</p>
<p>As a sidenote, <a href="http://weblog.jamisbuck.org/2008/2/28/capistrano-2-2-0">Capistrano 2.2.0 was released</a> by <a href="http://weblog.jamisbuck.org/">Jamis</a> last week.</p>
<p>This week’s report covers changes from 25 Feb 2008 to 2 Mar 2008 (the day the corresponding <a href="http://railsenvy.com/podcast/">Rails Envy podcast</a> was recorded).</p>
<h3>Time#end_of_XXX methods</h3>
<p>A bunch of Time core extension methods have been added. These are: <code>Time#end_of_day</code>, <code>Time#end_of_week</code>, <code>Time#end_of_year</code>, and <code>Time#end_of_quarter</code>, which all return exactly what you expect them to return:</p>
<pre><code class="ruby">Time.now.end_of_week # =&gt; Sun Mar 09 00:00:00 0800 2008</code></pre>
<p>Credit goes to <a href="http://www.workingwithrails.com/person/5065-juanjo-baz-n">Juanjo Bazán</a> (a former <a href="http://weblog.workingwithrails.com/2007/10/22/hackfest-winner-interview-juanjo-bazn">Rails Hackfest winner</a>) and <a href="http://www.workingwithrails.com/person/7168-tarmo-t-nav">Tarmo Tänav</a> for contributing this patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8934">http://dev.rubyonrails.org/changeset/8934</a></p>
<h3>Date helpers now accept HTML options</h3>
<p>ActionView&#8217;s date helpers (such as <code>date_select</code>, <code>time_select</code>, <code>select_datetime</code>) did not support any HTML options, unlike the other helpers (like <code>f.text_field(:name, :class => 'my_css_class', :size => 20)</code>). This inconsistency has been fixed and you can now finally do:</p>
<pre><code class="ruby">&lt;%= date_select 'user', 'birthday', :order =&gt; [:day], :class =&gt; 'my_css_class' %&gt;</code></pre>
<p><a href="http://www.workingwithrails.com/person/5430-murray-steele">Murray Steele</a> (h-lame on the Rails Trac) and <a hre="http://mentalized.net/">Jakob Skjerning</a> contributed this patch.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8968">http://dev.rubyonrails.org/changeset/8968</a></p>
<h3>No need for explicit respond_to for RJS templates</h3>
<p>ActionController has been changed so that JS requests will automatically render action.js.rjs files without the need to specify an explicit <code>respond_to</code> block. This means that your .rjs files work the same way as your .html.erb files &#8211; just put them in the right place and Rails will use it.</p>
<p>Related changeset: <a href="http://dev.rubyonrails.org/changeset/8956">http://dev.rubyonrails.org/changeset/8956</a></p>
<h3>Bugfixes</h3>
<ul>
<li>http://dev.rubyonrails.org/changeset/8937 &#8211; Prevent Rails from crashing when trying to deserialize an XML representation of a model named &#8220;Type&#8221; (using Hash#from_xml). Contributed by <a href="http://www.workingwithrails.com/person/5065-juanjo-baz-n">Juanjo Bazán</a> and <a href="http://www.workingwithrails.com/person/7102-isaac-feliu">Isaac Feliu</a>.</li>
<li>http://dev.rubyonrails.org/changeset/8942 &#8211; Fix eager loading so that it doesn&#8217;t pull in duplicate records in some cases. Contributed by Catfish.</li>
</ul>
<p>As usual, let me know of any inaccuracies or any suggestions you may have in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codefront.net/2008/03/05/living-on-the-edge-of-rails-10/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

