<?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>Phusion Corporate Blog &#187; Software</title>
	<atom:link href="http://blog.phusion.nl/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.phusion.nl</link>
	<description></description>
	<lastBuildDate>Thu, 19 Jan 2012 21:24:18 +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>default_value_for 1.0.5 released: default attribute values for ActiveRecord models</title>
		<link>http://blog.phusion.nl/2011/08/10/default_value_for-1-0-5-released-default-attribute-values-for-activerecord-models/</link>
		<comments>http://blog.phusion.nl/2011/08/10/default_value_for-1-0-5-released-default-attribute-values-for-activerecord-models/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 22:32:43 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=1395</guid>
		<description><![CDATA[We&#8217;ve just released default_value_for version 1.0.5. default_value_for is a Rails plugin for supporting default values in ActiveRecord models. Like this: class User &#60; ActiveRecord::Base default_value_for :age, 10 end User.new.age # => 10 You can read more about this plugin at Github. Version 1.0.5 fixes support for Rails 3.0 and Rails 3.1. Unfortunately we had to [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve just released <a href="https://github.com/FooBarWidget/default_value_for">default_value_for</a> version 1.0.5. default_value_for is a Rails plugin for supporting default values in ActiveRecord models. Like this:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :age, 10
end

User.new.age   # => 10</pre>
<p>You can read more about this plugin at <a href="https://github.com/FooBarWidget/default_value_for">Github</a>.</p>
<p>Version 1.0.5 fixes support for Rails 3.0 and Rails 3.1. Unfortunately we had to remove one feature due to changes in ActiveRecord 3.1. It is no longer possible to access associations in the default_value_for_block. The following is no longer possible:</p>
<pre>class User &lt; ActiveRecord::Base
  belongs_to &#58;organization

  default_value_for :name do |model|
    model.name = "Drone for #{model.organization.name}"
  end
end

evil_organization.name  # => "Evil Organization"
user = evil_organization.users.create
user.name               # => "Drone for Evil Organization"??</pre>
<p>One would expect the last expression to evaluate to &#8220;Drone for Evil Organization&#8221;. On Rails 2 and Rails 3.0, it does, but on Rails 3.1 it does not. Because of the way the &#8216;organization&#8217; attribute is assigned to the model by ActiveRecord, we are no longer able to support this behavior. Inside the default_value_for block, model.organization would evaluate to nil.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2011/08/10/default_value_for-1-0-5-released-default-attribute-values-for-activerecord-models/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Launching unofficial, automatically updated Github mirror for the Nginx SVN repository</title>
		<link>http://blog.phusion.nl/2011/08/09/launching-unofficial-automatically-updated-github-mirror-for-the-nginx-svn-repository/</link>
		<comments>http://blog.phusion.nl/2011/08/09/launching-unofficial-automatically-updated-github-mirror-for-the-nginx-svn-repository/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 16:34:42 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Nginx]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=1382</guid>
		<description><![CDATA[I probably don&#8217;t need to tell you what a great web server Nginx is. It&#8217;s lightweight, it&#8217;s fast, it&#8217;s scalable, and many people like it for its configuration file syntax yet flexible features. It&#8217;s no surprise that Nginx is doing a great job serving as a core for Phusion Passenger Standalone (our Ruby/Rails web application [...]]]></description>
			<content:encoded><![CDATA[<p>I probably don&#8217;t need to tell you what a great web server <a href="http://www.nginx.org/">Nginx</a> is. It&#8217;s lightweight, it&#8217;s fast, it&#8217;s scalable, and many people like it for its configuration file syntax yet flexible features. It&#8217;s no surprise that Nginx is doing a great job serving as a core for <a href="http://www.modrails.com/documentation/Users%20guide%20Standalone.html">Phusion Passenger Standalone</a> (our Ruby/Rails web application server which supports Apache and Nginx).</p>
<p>Nginx&#8217;s development has traditionally been behind closed doors. Nginx is written for the most part by one brilliant man, <a href="http://sysoev.ru/en/">Igor Sysoev</a>, who accepts patches on the Nginx mailing list. But for a long time there was no source repository with which contributors and interested people can track the development process, and no official bug tracker. All of that have changed in 2011. Igor has <a href="http://news.ycombinator.com/item?id=2776622">established Nginx as a company</a>. The Nginx SVN repository is now open to the public and a few days ago they even opened a <a href="http://trac.nginx.org/">Trac</a>. In short: a lot of great news lately.</p>
<h2>Announcing the Github Nginx mirror</h2>
<p>These days a lot of people have switched from Subversion to Git. When you&#8217;ve worked with Git for a while, Subversion probably feels archaic and unproductive. The &#8220;killer app&#8221; for Git is <a href="https://github.com/">Github</a>, which provides an unbeatable collaboration experience. Indeed, many projects that have switched to Github reported a dramatic increase in contributions!</p>
<p>In order to stimulate Nginx development, we&#8217;ve launched a Github mirror of the Nginx SVN repository:</p>
<ul>
<li>Github page: <a href="https://github.com/phusion/nginx">https://github.com/phusion/nginx</a></li>
<li>Git URL: git://github.com/phusion/nginx.git</li>
</ul>
<p>A few notes about this mirror:</p>
<ul>
<li>It&#8217;s automatically updated twice a day.</li>
<li>It&#8217;s read-only. <b>We don&#8217;t accept pull requests.</b> Changes should be sent to the <a href="http://www.nginx.org/en/support.html">Nginx mailing list</a> in the form of patches.</li>
<li>We intentionally don&#8217;t mirror all the branches and tags, only the most recent ones, because we don&#8217;t believe the old branches and tags are useful to anybody.</li>
<li>Please feel free to <a href="mailto:info@phusion.nl">contact us</a> if you have an issue with our mirror.</li>
</ul>
<p>Happy developing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2011/08/09/launching-unofficial-automatically-updated-github-mirror-for-the-nginx-svn-repository/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 3.0.0 final released</title>
		<link>http://blog.phusion.nl/2010/10/18/phusion-passenger-3-0-0-final-released/</link>
		<comments>http://blog.phusion.nl/2010/10/18/phusion-passenger-3-0-0-final-released/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 12:09:40 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=949</guid>
		<description><![CDATA[Phusion Passenger is an Apache and Nginx module for deploying Ruby web applications. It has a strong focus on ease of use, stability and performance. Phusion Passenger is built on top of tried-and-true, battle-hardened Unix technologies, yet at the same time introduces innovations not found in most traditional Unix servers. Since version 3.0 it can [...]]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://www.modrails.com/">Phusion Passenger</a> is an Apache and Nginx module for deploying Ruby web applications. It has a strong focus on ease of use, stability and performance. Phusion Passenger is built on top of tried-and-true, battle-hardened Unix technologies, yet at the same time introduces innovations not found in most traditional Unix servers. Since version 3.0 it can also run standalone without an external web server, making it not only easier for first-time users but also ideal on development environments.</em></p>
<div style="text-align: center"><a href="http://blog.phusion.nl/wp-content/uploads/2010/10/retweets.png"><img src="http://blog.phusion.nl/wp-content/uploads/2010/10/retweets.png" alt="" title="retweets" width="500" class="alignnone size-full exhibit wp-image-962" /></a><br />
<em>Thanks for all the support on Twitter everyone!</em></div>
<h2>What&#8217;s new compared to 2.2</h2>
<p>Phusion Passenger 3 is a major new release and brings about many, many improvements in the areas of performance, features and stability. It is fully compatible with the latest technologies such as Rails 3.0, Ruby 1.9.2, RVM and Bundler.</p>
<p>You can read about the improvements in Phusion Passenger 3 through a set of articles that we had written on this subject:</p>
<div class="float-right"><a href="http://blog.phusion.nl/wp-content/uploads/2010/01/performance.jpg"><img src="http://blog.phusion.nl/wp-content/uploads/2010/09/performance-small.jpg" alt="" title="" width="250" height="168" class="alignnone size-full wp-image-863 exhibit"></a></div>
<ul>
<li><a href="http://blog.phusion.nl/2010/06/10/the-road-to-passenger-3-technology-preview-1-performance-2/"><b>Technology Preview 1: Performance</b></a><br />
Phusion Passenger 3 can be up to <b>55% faster</b> than Phusion Passenger 2.2.</li>
<li><a href="http://blog.phusion.nl/2010/06/18/the-road-to-passenger-3-technology-preview-2-stability-robustness-availability-self-healing/"><b>Technology Preview 2: Stability, robustness, availability, self-healing</b></a><br />
We&#8217;ve implemented many safeguards to keep Phusion Passenger stable and running as much as possible.</li>
<li><a href="http://blog.phusion.nl/2010/07/01/the-road-to-passenger-3-technology-preview-3-closing-the-gap-between-development-and-production-rethinking-the-word-easy/"><b>Technology Preview 3: Closing the gap between development and production &amp; rethinking the word “easy”</b></a><br />
Describes how Phusion Passenger&#8217;s usage model differs from Mongrel&#8217;s, Thin&#8217;s and Unicorn&#8217;s and when one would prefer our model over the other and vice versa.<br />
Introduces Phusion Passenger Standalone (formerly called Phusion Passenger Lite) which can be used as a potentially improved replacement for Mongrel, Thin and Unicorn.</li>
<li><a href="http://blog.phusion.nl/2010/07/29/the-road-to-passenger-3-technology-preview-4-adding-new-features-and-removing-old-limitations/"><b>Technology Preview 4: Adding new features and removing old limitations</b></a></li>
<li><a href="http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/"><b>Bonus article: Phusion Passenger &amp; running multiple Ruby versions</b></a></li>
</ul>
<h2>What&#8217;s new compared to 3.0.0 RC 1</h2>
<dl>
<dt>[Apache] `passenger-install-apache2-module &#8211;snippet` no longer prints ANSI color codes</dt>
<dd>This makes it possible to pipe its output directly to a config file. Fixes <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=548">issue #548</a>.</dd>
<dt>[Apache] Fixed thread stack size problems on FreeBSD</dt>
<dd>Previously it might crash for bizarre reasons.</dd>
<dt>[Nginx] Upgraded to Nginx 0.8.52 by default</dt>
<dd>This is because Nginx 0.8 has recently become the stable release series.</dd>
<dt>[Standalone] Fixed Unix domain socket support</dt>
<dd>There was a bug in Phusion Passenger Standalone which would cause the `-S` option to fail.</dd>
</dl>
<h2>How do I upgrade to 3.0.0?</h2>
<h3>Via a gem</h3>
<p>First install the gem with the following command:</p>
<pre>gem install passenger</pre>
<p>If you&#8217;re using Phusion Passenger for Apache or for Nginx, then re-run the Apache or Nginx module installer, whichever is appropriate:</p>
<pre>passenger-install-apache2-module
passenger-install-nginx-module</pre>
<p>At the end the installer will tell you to paste a configuration snippet into your web server config file. Replace the old snippet that you already had with this new one.</p>
<p>Phusion Passenger Standalone users don&#8217;t need to run anything else. Whenever you type</p>
<pre>passenger start</pre>
<p>it will automatically upgrade itself.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided Ubuntu packages for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 3.0.0, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/10/18/phusion-passenger-3-0-0-final-released/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 3.0.0 RC 1 released</title>
		<link>http://blog.phusion.nl/2010/10/01/phusion-passenger-3-0-0-rc-1-released/</link>
		<comments>http://blog.phusion.nl/2010/10/01/phusion-passenger-3-0-0-rc-1-released/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 10:34:37 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=943</guid>
		<description><![CDATA[This is it, the first Release Candidate (internally named &#8220;pre 4&#8243;). A few more bugs have been fixed since beta 3, but if no more serious bugs are found then the next release will be 3.0.0 final. What&#8217;s new Autodetection of Ruby tool commands now take exe extension, &#8211;program-prefix and &#8211;program-suffix into account Phusion Passenger [...]]]></description>
			<content:encoded><![CDATA[<p>This is it, the first Release Candidate (internally named &#8220;pre 4&#8243;). A few more bugs have been fixed since beta 3, but if no more serious bugs are found then the next release will be 3.0.0 final.</p>
<h2>What&#8217;s new</h2>
<dl>
<dt>Autodetection of Ruby tool commands now take exe extension, &#8211;program-prefix and &#8211;program-suffix into account</dt>
<dd>
<p>Phusion Passenger <a href="http://github.com/FooBarWidget/passenger/blob/release-3.0.0.pre3/lib/phusion_passenger/platform_info/ruby.rb#L240-290">had a pretty elaborate way</a> of searching the system for Ruby tool commands like &#8216;gem&#8217;, &#8216;rake&#8217;, etc. The reason why all this search code exists is because the problem is much more complicated than just searching for &#8220;rake&#8221; in $PATH. A significant number of people have multiple Ruby versions installed on their system; let&#8217;s call these Ruby A and Ruby B. They run the Phusion Passenger installer with Ruby A and they installed the required gems with Ruby A&#8217;s RubyGems, but they have a Rake in $PATH that belongs to Ruby B. If we were to naively use the Rake in $PATH then the wrong Rake will be invoked and they would wonder why the gems they just installed aren&#8217;t detected. Our Ruby tool search code tries very hard to find the Rake that belongs to the Ruby interpreter that&#8217;s currently running.</p>
<p>However the code didn&#8217;t take the exe extension into consideration, as well as the &#8211;program-prefix and &#8211;program-suffix that Ruby could be configured with. For example, on some systems the Ruby command is called &#8220;ruby1.8&#8243; and Rake is called &#8220;rake1.8&#8243;. Similarly, the default JRuby binary distribution calls Rake &#8220;jrake&#8221;. We&#8217;ve now updated our search code to take this into account as well. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=537">Issue #537.</a></p>
<p><b>Usability and ease of installation remains to be one of our biggest goals. As you can see we&#8217;ve gone through great lengths to make sure that everything works as expected and that everything is as fool-proof as possible, even if the system might not be entirely correctly configured.</b></p>
</dd>
<dt>Fixed linking problems on some systems</dt>
<dd>Phusion Passenger uses math functions such as <code>pow()</code>. On some systems &#8212; .e.g. NetBSD, some versions of Solaris and some Linux distros &#8212; this requires Phusion Passenger to be linked to the Math library. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=539">Issue #539.</a></dd>
<dt>Phusion Passenger Standalone fix</dt>
<dd>When Phusion Passenger Standalone is daemonized with -d, it exits with a non-zero exit code. This has been fixed. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=536">Issue #536.</a></dd>
<dt>Preferred PCRE version upgraded to version 8.10</dt>
<dd>passenger-install-nginx-module automatically installs PCRE for you in case you didn&#8217;t already have it.</dd>
</dl>
<h2>Installation/upgrade</h2>
<p>First install the latest Phusion Passenger gem:</p>
<pre>gem install passenger --pre</pre>
<p>(Or you can download the <a href="http://rubyforge.org/frs/download.php/72698/passenger-3.0.0.pre4.tar.gz">tarball</a>.)</p>
<p>If you want to install or upgrade the Apache or Nginx version, then run the installer as you&#8217;re used to:</p>
<pre>passenger-install-apache2-module
passenger-install-nginx-module</pre>
<p>At the end the installer will tell you to paste a configuration snippet. If you&#8217;re upgrading then replace the old snippet with the new one.</p>
<p>If you want to run Phusion Passenger Standalone, then run:</p>
<pre>cd /path-to-your-app
passenger start</pre>
<p>No special upgrade instructions needed.</p>
<h2>The documentation</h2>
<p><a href="http://www.modrails.com/documentation/Users guide Apache 3.0.html">Users guide for Apache</a><br />
<a href="http://www.modrails.com/documentation/Users guide Nginx 3.0.html">Users guide for Nginx</a><br />
<a href="http://www.modrails.com/documentation/Users guide Standalone 3.0.html">Users guide for Standalone</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/10/01/phusion-passenger-3-0-0-rc-1-released/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 3.0.0 public beta 3 released</title>
		<link>http://blog.phusion.nl/2010/09/20/phusion-passenger-3-0-0-public-beta-3-released/</link>
		<comments>http://blog.phusion.nl/2010/09/20/phusion-passenger-3-0-0-public-beta-3-released/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 17:13:46 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=893</guid>
		<description><![CDATA[What&#8217;s new More RVM issues fixed A lot of people who happen to use RVM have reported various problems. Some of the symptoms include: The spawn server crashes during startup. Phusion Passenger Standalone prints &#8216;command not found&#8217; errors. It turned out that these problems occur when one has an older RVM version installed. Phusion Passenger [...]]]></description>
			<content:encoded><![CDATA[<h2>What&#8217;s new</h2>
<dl>
<dt>More RVM issues fixed</dt>
<dd>A lot of people who happen to use RVM have reported various problems. Some of the symptoms include:</p>
<ul>
<li>The spawn server crashes during startup.</li>
<li>Phusion Passenger Standalone prints &#8216;command not found&#8217; errors.</li>
</ul>
<p>It turned out that these problems occur when one has an older RVM version installed. Phusion Passenger depends on features provided by relatively new RVM versions. We&#8217;ve added sanity checks in Phusion Passenger so that it warns you if it detects an old RVM installation.</p>
<p>You can upgrade your RVM installation by running these commands:</p>
<pre>rvm update --head
rvm reload
rvm repair all</pre>
<p>We&#8217;ve also fixed support for system-wide RVM installs.</dd>
<dt>Aggressively checks for permissions</dt>
<dd>Many problems that people report on the Phusion Passenger discussion board are actually caused by wrong permissions set on the application files or on one of the parent directories. We&#8217;ve added aggressive permission checking code in Phusion Passenger. If any permissions are wrong then it will tell the user exactly which directory has wrong permissions and how to fix it. This should make Phusion Passenger a lot more fail-proof than before.</dd>
<dt>Fixed some more compilation problems</dt>
<dd>These problems occur on some systems but not on others.</dd>
<dt>Fixed passenger-status crash</dt>
<dd>When passenger-status tries to tell the user that it needs to be run as root, it used to crash instead because of a typo.</dd>
<dt>Phusion Passenger Standalone checks for GNU make on FreeBSD</dt>
<dd>Phusion Passenger Standalone depends on the GNU version of make in order to be able to show a compilation progress bar.</dd>
</dl>
<h2>Installation/upgrade</h2>
<p>First install the latest Phusion Passenger gem:</p>
<pre>gem install passenger --pre</pre>
<p>(Or you can download the <a href="http://rubyforge.org/frs/download.php/72553/passenger-3.0.0.pre3.tar.gz">tarball</a>.)</p>
<p>If you want to install or upgrade the Apache or Nginx version, then run the installer as you&#8217;re used to:</p>
<pre>passenger-install-apache2-module
passenger-install-nginx-module</pre>
<p>At the end the installer will tell you to paste a configuration snippet. If you&#8217;re upgrading then replace the old snippet with the new one.</p>
<p>If you want to run Phusion Passenger Standalone, then run:</p>
<pre>cd /path-to-your-app
passenger start</pre>
<p>No special upgrade instructions needed.</p>
<h2>The documentation</h2>
<p><a href="http://www.modrails.com/documentation/Users guide Apache 3.0.html">Users guide for Apache</a><br />
<a href="http://www.modrails.com/documentation/Users guide Nginx 3.0.html">Users guide for Nginx</a><br />
<a href="http://www.modrails.com/documentation/Users guide Standalone 3.0.html">Users guide for Standalone</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/09/20/phusion-passenger-3-0-0-public-beta-3-released/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 3.0.0 public beta 2 released</title>
		<link>http://blog.phusion.nl/2010/09/17/phusion-passenger-3-0-0-public-beta-2-released/</link>
		<comments>http://blog.phusion.nl/2010/09/17/phusion-passenger-3-0-0-public-beta-2-released/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 16:15:07 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=890</guid>
		<description><![CDATA[Thanks to all the users who have provided constructive feedback! This release fixes all newly reported issues so far. Phusion Passenger Standalone now correctly handles paths with spaces in them Beta 1 would error out with a weird message. Fixed some RVM support issues If you&#8217;re using RVM and you had problems with beta 1, [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to all the users who have provided constructive feedback! This release fixes all newly reported issues so far.</p>
<dl>
<dt>Phusion Passenger Standalone now correctly handles paths with spaces in them</dt>
<dd>Beta 1 would error out with a weird message.</dd>
<dt>Fixed some RVM support issues</dt>
<dd>If you&#8217;re using RVM and you had problems with beta 1, try this version. Thanks to Wayne for helping out!</dd>
<dt>Improved watchdog startup error checking</dt>
<dd>If the watchdog crashes during startup then the reason wasn&#8217;t always obvious. We&#8217;ve improved the startup error checking code so that more error information can be collected.</dd>
<dt>Fixed Phusion Passenger Standalone binary compatibility string generation</dt>
<dd>The binary compatibility string is generated from many components, including part of the output of &#8216;uname -p&#8217;. It turns out that on some systems that command outputs in an unexpected format.</dd>
<dt>Fixed curl error detection</dt>
<dd>Curl is used to download things when wget is not available. Beta 1 did not correctly recognize cases in which curl exit because of an HTTP 404 error.</dd>
<dt>Fixed PassengerMinInstances default value on Apache</dt>
<dd>It&#8217;s supposed to be 1, but in beta 1 it was accidentally still 0.</dd>
<dt>Fixed support for older Apache 2 versions</dt>
<dd>Beta 1 used API calls which are only available in newer versions.</dd>
<dt>Fixed various compilation warnings</dt>
<dd>Including warnings on CentOS 5 and Ubuntu 10.04.</dd>
</dl>
<h2>Installation/upgrade</h2>
<p>First install the latest Phusion Passenger gem:</p>
<pre>gem install passenger --pre</pre>
<p>(Or you can download the <a href="http://rubyforge.org/frs/download.php/72539/passenger-3.0.0.pre2.tar.gz">tarball</a>.)</p>
<p>If you want to install or upgrade the Apache or Nginx version, then run the installer as you&#8217;re used to:</p>
<pre>passenger-install-apache2-module
passenger-install-nginx-module</pre>
<p>At the end the installer will tell you to paste a configuration snippet. If you&#8217;re upgrading then replace the old snippet with the new one.</p>
<p>If you want to run Phusion Passenger Standalone, then run:</p>
<pre>cd /path-to-your-app
passenger start</pre>
<p>No special upgrade instructions needed.</p>
<h2>The documentation</h2>
<p><a href="http://www.modrails.com/documentation/Users guide Apache 3.0.html">Users guide for Apache</a><br />
<a href="http://www.modrails.com/documentation/Users guide Nginx 3.0.html">Users guide for Nginx</a><br />
<a href="http://www.modrails.com/documentation/Users guide Standalone 3.0.html">Users guide for Standalone</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/09/17/phusion-passenger-3-0-0-public-beta-2-released/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 3.0.0 public beta 1 is out!</title>
		<link>http://blog.phusion.nl/2010/09/15/phusion-passenger-3-0-0-public-beta-1-is-out/</link>
		<comments>http://blog.phusion.nl/2010/09/15/phusion-passenger-3-0-0-public-beta-1-is-out/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 12:59:53 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=859</guid>
		<description><![CDATA[Phusion Passenger is software with which one can deploy Ruby web applications on the Apache or Nginx web server. Now, with the release of version 3.0.0 beta 1, it also comes with a standalone version that does not require an external web server. Please read http://www.modrails.com/ for details. In the past period we&#8217;ve blogged extensively [...]]]></description>
			<content:encoded><![CDATA[<p><em>Phusion Passenger is software with which one can deploy Ruby web applications on the Apache or Nginx web server. Now, with the release of version 3.0.0 beta 1, it also comes with a standalone version that does not require an external web server. Please read <a href="http://www.modrails.com/">http://www.modrails.com/</a> for details.</em></p>
<p>In the past period we&#8217;ve blogged extensively about the progress of Phusion Passenger 3. Many exciting changes have been introduced. It&#8217;s been a long ride, but today we are happy to announce the first Phusion Passenger 3 public beta! We&#8217;ve already tested Phusion Passenger 3 extensively in private, and now we&#8217;re giving the community a chance to test it as well in order to make the final release rock-solid.</p>
<p>We&#8217;ve received a lot of emails from people who are excited about Phusion Passenger 3. Thank you all for your support!</p>
<p>To recap, we&#8217;ve described Phusion Passenger 3 extensively in our past Technology Preview articles:</p>
<div class="float-right"><a href="http://blog.phusion.nl/wp-content/uploads/2010/01/performance.jpg"><img src="http://blog.phusion.nl/wp-content/uploads/2010/09/performance-small.jpg" alt="" title="" width="250" height="168" class="alignnone size-full wp-image-863 exhibit"></a></div>
<ul>
<li><a href="http://blog.phusion.nl/2010/06/10/the-road-to-passenger-3-technology-preview-1-performance-2/"><b>Technology Preview 1: Performance</b></a><br />
Phusion Passenger 3 can be up to <b>55% faster</b> than Phusion Passenger 2.2.</li>
<li><a href="http://blog.phusion.nl/2010/06/18/the-road-to-passenger-3-technology-preview-2-stability-robustness-availability-self-healing/"><b>Technology Preview 2: Stability, robustness, availability, self-healing</b></a><br />
We&#8217;ve implemented many safeguards to keep Phusion Passenger stable and running as much as possible.</li>
<li><a href="http://blog.phusion.nl/2010/07/01/the-road-to-passenger-3-technology-preview-3-closing-the-gap-between-development-and-production-rethinking-the-word-easy/"><b>Technology Preview 3: Closing the gap between development and production &amp; rethinking the word “easy”</b></a><br />
Describes how Phusion Passenger&#8217;s usage model differs from Mongrel&#8217;s, Thin&#8217;s and Unicorn&#8217;s and when one would prefer our model over the other and vice versa.<br />
Introduces Phusion Passenger Standalone (formerly called Phusion Passenger Lite) which can be used as a potentially improved replacement for Mongrel, Thin and Unicorn.</li>
<li><a href="http://blog.phusion.nl/2010/07/29/the-road-to-passenger-3-technology-preview-4-adding-new-features-and-removing-old-limitations/"><b>Technology Preview 4: Adding new features and removing old limitations</b></a></li>
</ul>
<p>Except for mass deployment, all features described in the technology previews are available as open source in Phusion Passenger 3. A few more changes have been made since the last Technology Preview:</p>
<dl>
<dt>The &#8216;PassengerPreStart&#8217; option</dt>
<dd>In Technology Preview 4 we described PassengerMinInstances. That option ensures that, at least x instances will be kept around once they&#8217;ve been spawned, but it does not ensure that instances are immediately spawned up during web server start. Instead we have a separate configuration option for that, called PassengerPreStart. PassengerPreStart and PassengerMinInstances and the reason why they&#8217;re separate configuration options are described extensively in the manual.</dd>
<dt>RVM support</dt>
<dd>RVM is becoming more and more popular. Previous versions of Phusion Passenger work fine with RVM, but one has to <a href="http://rvm.beginrescueend.com/integration/passenger/">follow special installation instructions</a> for it to work properly. We&#8217;ve noticed that many users are not aware of this and as a result couldn&#8217;t get Phusion Passenger working properly with RVM. In Phusion Passenger 3 we&#8217;ve collaborated with Wayne E. Seguin and added special support for RVM so that everything should work out-of-the-box, without special installation instructions.</dd>
</dl>
<h2>Other minor changes</h2>
<p>For completeness, here are a list of minor changes that have not been described in the Technology Previews so far:</p>
<ul>
<li>Nginx is now compiled with SSL support by default.</li>
<li>Nginx can now be compiled on a noexec /tmp filesystem. Fixes <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=380">bug #380</a>.</li>
<li>Support for Nginx 0.8.</li>
<li>Dropped support for Nginx 0.6.</li>
<li>Much better Ruby 1.9.2 support. Our unit test suite has been refactored; Ruby 1.9.2 passes our unit test suite 100%.</li>
<li>The <b>PassengerFriendlyErrorPages</b> option has been added. This allows you to turn off the friendly error pages that Phusion Passenger normally displays in the event of an error, so that only a standard 500 error page is shown. This is documented in the manual.</li>
<li>The <b>PassengerDebugLogFile</b> option has been added. This is documented in the manual.</li>
<li>User switching support has been made more flexible through the <b>PassengerUser</b>, <b>PassengerGroup</b>, <b>PassengerDefaultUser</b> and <b>PassengerDefaultGroup</b> options. These are documented in the manual.</li>
<li><b>RailsSpawnMethod</b> has been renamed to <b>PassengerSpawnMethod</b> because we now support smart spawning for Rack apps as well.</li>
<li>passenger-install-apache2-module and passenger-install-nginx-module can now be run concurrently without the one deleting files compiled by the other.</li>
<li>#at_exit blocks are now called during application process shutdown.</li>
<li>passenger-install-apache2-module now supports a &#8211;snippet option. When this option is given, the command outputs the Apache configuration snippet that should be pasted, but doesn&#8217;t do anything else.</li>
<li>Temporary files that Phusion Passenger places in /tmp are touched every 6 hours. This prevents /tmp cleaner daemons that are present on many systems from deleting these temp files that are essential for Phusion Passenger&#8217;s functioning. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=365">Bug #365.</a></li>
</ul>
<h2>Install</h2>
<p>Installation is almost the same as Phusion Passenger 2. Type:</p>
<pre>gem install passenger --pre</pre>
<p>If you want to install the Apache or Nginx version, then run the installer as you&#8217;re used to:</p>
<pre>passenger-install-apache2-module
passenger-install-nginx-module</pre>
<p>Or you can download the <a href="http://rubyforge.org/frs/download.php/72496/passenger-3.0.0.pre1.tar.gz">tarball</a>.</p>
<p>If you want to run Phusion Passenger Standalone, then run:</p>
<pre>cd /path-to-your-app
passenger start</pre>
<h2>The documentation</h2>
<p><a href="http://www.modrails.com/documentation/Users guide Apache 3.0.html">Users guide for Apache</a><br />
<a href="http://www.modrails.com/documentation/Users guide Nginx 3.0.html">Users guide for Nginx</a><br />
<a href="http://www.modrails.com/documentation/Users guide Standalone 3.0.html">Users guide for Standalone</a></p>
<h2>Things to come</h2>
<p>Although Phusion Passenger 3.0 brings many exciting improvements, it is only the beginning. In parallel to Phusion Passenger 3, we have been working on some interesting things which we plan to reveal to the world shortly after the release of Phusion Passenger 3.0. Please stay tuned for future developments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/09/15/phusion-passenger-3-0-0-public-beta-1-is-out/feed/</wfw:commentRss>
		<slash:comments>70</slash:comments>
		</item>
		<item>
		<title>Announcing EncryptedCookieStore plugin for Rails 2.3</title>
		<link>http://blog.phusion.nl/2010/04/13/announcing-encryptedcookiestore-plugin-for-rails-2-3/</link>
		<comments>http://blog.phusion.nl/2010/04/13/announcing-encryptedcookiestore-plugin-for-rails-2-3/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 21:46:28 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=599</guid>
		<description><![CDATA[EncryptedCookieStore is similar to Ruby on Rails&#8217;s CookieStore (it saves session data in a cookie), but it uses encryption so that people can&#8217;t read what&#8217;s in the session data. This makes it possible to store sensitive data in the session. EncryptedCookieStore is written for Rails 2.3. Other versions of Rails have not been tested. Note: [...]]]></description>
			<content:encoded><![CDATA[<p>EncryptedCookieStore is similar to Ruby on Rails&#8217;s CookieStore (it saves session data in a cookie), but it uses encryption so that people can&#8217;t read what&#8217;s in the session data. This makes it possible to store sensitive data in the session.</p>
<p>EncryptedCookieStore is written for Rails 2.3. Other versions of Rails have not been tested.</p>
<p><b>Note</b>: This is <i>not</i> ThinkRelevance&#8217;s EncryptedCookieStore. In the Rails 2.0 days they wrote an EncryptedCookieStore, but it seems their repository had gone defunct and their source code lost. This EncryptedCookieStore is written from scratch by Phusion.</p>
<p>Source code at <a href="http://github.com/FooBarWidget/encrypted_cookie_store">http://github.com/FooBarWidget/encrypted_cookie_store</a></p>
<h2>Installation and usage</h2>
<p>First, install it:</p>
<pre>./script/plugin install git://github.com/FooBarWidget/encrypted_cookie_store.git</pre>
<p>Then edit <tt>config/initializers/session_store.rb</tt> and set your session store to EncryptedCookieStore:</p>
<pre>ActionController::Base.session_store = EncryptedCookieStore</pre>
<p>You need to set a few session options before EncryptedCookieStore is usable. You must set all options that CookieStore needs, plus an encryption key that EncryptedCookieStore needs. In <tt>session_store.rb</tt>:</p>
<pre lang="ruby">
ActionController::Base.session = {
        # CookieStore options...
        :key            => '_session',     # Name of the cookie which contains the session data.
        :secret         => 'b4589cc9...',  # A secret string used to generate the checksum for
                                           # the session data. Must be longer than 64 characters
                                           # and be completely random.

        # EncryptedCookieStore options...
        :encryption_key => 'c306779f3...', # The encryption key. See below for notes.
}</pre>
<p>The encryption key <b>must</b> be a hexadecimal string of exactly 32 bytes. It should be entirely random, because otherwise it can make the encryption weak.</p>
<p>You can generate a new encryption key by running <tt>rake secret:encryption_key</tt>. This command will output a random encryption key that you can then copy and paste into your environment.rb.</p>
<h2>Operational details</h2>
<p>Upon generating cookie data, EncryptedCookieStore generates a new, random initialization vector for encrypting the session data. This initialization vector is then encrypted with 128-bit AES in ECB mode. The session data is first protected with an HMAC to prevent tampering. The session data, along with the HMAC, are then encrypted using 256-bit AES in CFB mode with the generated initialization vector. This encrypted session data + HMAC are then stored, along with the encrypted initialization vector, into the cookie.</p>
<p>Upon unmarshalling the cookie data, EncryptedCookieStore decrypts the encrypted initialization vector and use that to decrypt the encrypted session data + HMAC. The decrypted session data is then verified against the HMAC.</p>
<p>The reason why HMAC verification occurs after decryption instead of before decryption is because we want to be able to detect changes to the encryption key and changes to the HMAC secret key, as well as migrations from CookieStore. Verifying after decryption allows us to automatically invalidate such old session cookies.</p>
<p>EncryptedCookieStore is quite fast: it is able to marshal and unmarshal a simple session object 5000 times in 8.7 seconds on a MacBook Pro with a 2.4 Ghz Intel Core 2 Duo (in battery mode). This is about 0.174 ms per marshal+unmarshal action. See <tt>rake benchmark</tt> in the EncryptedCookieStore sources for details.</p>
<h2>EncryptedCookieStore vs other session stores</h2>
<p>EncryptedCookieStore inherits all the benefits of CookieStore:</p>
<ul>
<li>It works out of the box without the need to setup a seperate data store (e.g. database table, daemon, etc).</li>
<li>It does not require any maintenance. Old, stale sessions do not need to be manually cleaned up, as is the case with PStore and ActiveRecordStore.</li>
<li>Compared to MemCacheStore, EncryptedCookieStore can &#8220;hold&#8221; an infinite number of sessions at any time.</li>
<li>It can be scaled across multiple servers without any additional setup.</li>
<li>It is fast.</li>
<li>It is more secure than CookieStore because it allows you to store sensitive data in the session.</li>
</ul>
<p>There are of course drawbacks as well:</p>
<ul>
<li>It is prone to session replay attacks. These kind of attacks are explained in the <a href="http://guides.rubyonrails.org/security.html#session-storage">Ruby on Rails Security Guide</a>. Therefore you should never store anything along the lines of <tt>is_admin</tt> in the session.</li>
<li>You can store at most a little less than 4 KB of data in the session because that&#8217;s the size limit of a cookie. &#8220;A little less&#8221; because EncryptedCookieStore also stores a small amount of bookkeeping data in the cookie.</li>
<li>Although encryption makes it more secure than CookieStore, there&#8217;s still a chance that a bug in EncryptedCookieStore renders it insecure. We welcome everyone to audit this code. There&#8217;s also a chance that weaknesses in AES are found in the near future which render it insecure. If you are storing *really* sensitive information in the session, e.g. social security numbers, or plans for world domination, then you should consider using ActiveRecordStore or some other server-side store.</li>
</ul>
<h2>JRuby: Illegal Key Size error</h2>
<p>If you get this error (and your code works with MRI)&#8230;</p>
<pre>    Illegal key size

    [...]/vendor/plugins/encrypted_cookie_store/lib/encrypted_cookie_store.rb:62:in `marshal'</pre>
<p>&#8230;then it probably means you don&#8217;t have the &#8220;unlimited strength&#8221; policy files installed for your JVM. <a href="http://www.ngs.ac.uk/tools/jcepolicyfiles">Download and install them.</a> You probably have the &#8220;strong&#8221; version if they are already there.</p>
<p>As a workaround, you can change the cipher type from 256-bit AES to 128-bit by<br />
inserting the following in <tt>config/initializer/session_store.rb</tt>:</p>
<pre>EncryptedCookieStore.data_cipher_type = 'aes-128-cfb'.freeze  # was 256</pre>
<p>Please note that after changing to 128-bit AES, EncryptedCookieStore still requires a 32 bytes hexadecimal encryption key, although only half of the key is actually used.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/04/13/announcing-encryptedcookiestore-plugin-for-rails-2-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Securely store passwords with bcrypt-ruby; now compatible with JRuby and Ruby 1.9</title>
		<link>http://blog.phusion.nl/2009/08/13/securely-store-passwords-with-bcrypt-ruby-now-compatible-with-jruby-and-ruby-1-9/</link>
		<comments>http://blog.phusion.nl/2009/08/13/securely-store-passwords-with-bcrypt-ruby-now-compatible-with-jruby-and-ruby-1-9/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 21:03:34 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=316</guid>
		<description><![CDATA[When writing web applications, or any application for that manner, any passwords should be stored securely. As a rule of thumb, one should never store passwords as clear text in the database for the following reasons: If the database ever gets leaked out, then all accounts are compromised until every single user resets his password. [...]]]></description>
			<content:encoded><![CDATA[<p>When writing web applications, or any application for that manner, any passwords should be stored securely. As a rule of thumb, one should never store passwords as clear text in the database for the following reasons:</p>
<ul>
<li>If the database ever gets leaked out, then all accounts are compromised until every single user resets his password. Imagine that you&#8217;re an MMORPG developer; leaking out the database with clear text passwords allows the attacker to delete every player&#8217;s characters.</li>
<li>Many people use the same password for multiple sites. Imagine that the password stored in your database is also used for the user&#8217;s online banking account. Even if the database does not get leaked out, the password is still visible to the system administrator; this can be a privacy breach.</li>
</ul>
<p>There are several &#8220;obvious&#8221; alternatives, which aren&#8217;t quite secure enough:</p>
<dl>
<dt>Storing passwords as MD5/SHA1/$FAVORITE_ALGORITHM hashes</dt>
<dd>These days MD5 can be brute-force cracked with relatively little effort. SHA1, SHA2 and other algorithms are harder to brute-force, but the attacker can still crack these hashes by using <em>rainbow tables</em>: precomputed tables of hashes with which the attacker can look up the input for a hash with relative ease. This rainbow table does not have to be very large: it just has to contain words from the dictionary, because many people use dictionary words as passwords.</p>
<p>Using plain hashes also makes it possible for an attacker to determine whether two users have the same password.</dd>
<dt>Encrypting the password</dt>
<dd>This is not a good idea because if the attacker was able to steal the database, then there&#8217;s a possibility that he&#8217;s able to steal the key file as well. Plus, the system administrator is able to read everybody&#8217;s passwords, unless he&#8217;s restricted access to either the key file or the database.</dd>
</dl>
<p>The solution is to store passwords as <em>salted hashes</em>. One calculates a salted hash as follows:</p>
<pre>salted_hash = hashing_algorithm(salt + cleartext_password)</pre>
<p>Here, <code>salt</code> is a random string. After calculating the salted hash, one should store the salted hash in the database, along with the (cleartext) salt. It is not necessary to keep the salt secret or to obfuscate it.</p>
<p>When a user logs in, one can verify his password by re-computing the salted hash and comparing it with the salted hash in the database:</p>
<pre>salted_hash = hashing_algorithm(salt_from_database + user_provided_password)
if (salted_hash == salted_hash_from_database):
    user is logged in
else:
    password incorrect</pre>
<p>The usage of the salt forces the attacker to either brute-force the hash or to use a ridiculously large rainbow table. In case of the latter, the sheer size of the required rainbow table can make it unpractical to generate. The larger the salt, the more difficult it becomes for the cracker to use rainbow tables.</p>
<p>However, even with salting, one should still not use SHA1, SHA2, Whirlpool or most other hashing algorithms because these algorithms are designed to be fast. Although brute forcing SHA2 and Whirlpool is hard, it&#8217;s still possible given sufficient resources. Instead, one should pick a hashing algorithm that&#8217;s designed to be <b>slow</b> so that brute forcing becomes unfeasible. Bcrypt is such a slow hashing algorithm. A speed comparison on a MacBook Pro with 2 Ghz Intel Core 2 Duo:</p>
<ul>
<li>SHA-1: 118600 hashes per second.</li>
<li>Bcrypt (with cost = 10): 7.7 hashes per second.</li>
</ul>
<p>Theoretically it would take 4*10^35 years for a single MacBook Pro core to crack an SHA-1 hash, assuming that the attacker does not harness any weaknesses in SHA-1. To crack a bcrypt hash one would need 6*10^39 years, or 10000 more times. Therefore, we recommend the use of bcrypt to store passwords securely.</p>
<p>There&#8217;s even a nice Ruby implementation of this algorithm: <a href="http://bcrypt-ruby.rubyforge.org/">bcrypt-ruby</a>! Up until recently, bcrypt-ruby was only available for MRI (&#8220;Matz Ruby Interpreter&#8221;, the C implementation that most people use). However, we&#8217;ve made it compatible with JRuby! The code can be found in <a href="http://github.com/FooBarWidget/bcrypt-ruby/tree/java">our fork at Github</a>. The current version also has issues with Ruby 1.9, which we&#8217;ve fixed as well. The author of bcrypt-ruby has already <a href="http://github.com/codahale/bcrypt-ruby/tree">accepted</a> our changes and will soon release a new version with JRuby and Ruby 1.9 support.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2009/08/13/securely-store-passwords-with-bcrypt-ruby-now-compatible-with-jruby-and-ruby-1-9/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>default_value_for Rails plugin: declaratively define default values for ActiveRecord models</title>
		<link>http://blog.phusion.nl/2008/10/03/47/</link>
		<comments>http://blog.phusion.nl/2008/10/03/47/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 15:13:31 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=47</guid>
		<description><![CDATA[Introduction The default_value_for plugin allows one to define default values for ActiveRecord models in a declarative manner. For example: class User &#60; ActiveRecord::Base default_value_for :name, "(no name)" default_value_for :last_seen do Time.now end end u = User.new u.name # =&#62; "(no name)" u.last_seen # =&#62; Mon Sep 22 17:28:38 +0200 2008 We at Phusion use it [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>The default_value_for plugin allows one to define default values for ActiveRecord models in a declarative manner. For example:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :name, "(no name)"
  default_value_for :last_seen do
    Time.now
  end
end

u = User.new
u.name       # =&gt; "(no name)"
u.last_seen  # =&gt; Mon Sep 22 17:28:38 +0200 2008</pre>
<p>We at Phusion use it for generating UUIDs for models.</p>
<p><b>Note</b>: critics might be interested in the &#8220;When (not) to use default_value_for?&#8221; section. Please read on.</p>
<h2>Installation</h2>
<p>Install with:</p>
<pre>./script/plugin install git://github.com/FooBarWidget/default_value_for.git</pre>
<p>See also <a href="http://agilewebdevelopment.com/plugins/default_value_for">the AgileWebDevelopment Plugins</a> entry.</p>
<p>If you like this plugin, then please <a href="http://www.modrails.com/enterprise.html">consider donating</a> and/or recommending us:</p>
<table class="wwr">
<tr>
<td>
<a href="http://www.workingwithrails.com/person/11402-hongli-lai"><img src="http://workingwithrails.com/images/tools/compact-small.jpg"/> Hongli Lai</a>
</td>
<td>
<a href="http://www.workingwithrails.com/person/12429-ninh-bui"><img src="http://workingwithrails.com/images/tools/compact-small.jpg"/> Ninh Bui</a>
</td>
</tr>
</table>
<h2>The default_value_for method</h2>
<p>The <code>default_value_for</code> method is available in all ActiveRecord model classes.</p>
<p>The first argument is the name of the attribute for which a default value should be set. This may either be a Symbol or a String.</p>
<p>The default value itself may either be passed as the second argument:</p>
<pre>default_value_for :age, 20</pre>
<p>&#8230;or it may be passed as the return value of a block:</p>
<pre>default_value_for :age do
  if today_is_sunday?
    20
  else
    30
  end
end</pre>
<p>If you pass a value argument, then the default value is static and never changes. However, if you pass a block, then the default value is retrieved by calling the block. This block is called not once, but every time a new record is instantiated and default values need to be filled in.</p>
<p>The latter form is especially useful if your model has a UUID column. One can generate a new, random UUID for every newly instantiated record:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :uuid do
    UuidGenerator.new.generate_uuid
  end
end

User.new.uuid  # =&gt; "51d6d6846f1d1b5c9a...."
User.new.uuid  # =&gt; "ede292289e3484cb88...."</pre>
<p>Note that record is passed to the block as an argument, in case you need it for whatever reason:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :uuid do |x|
    x   # &lt;--- a User object
    UuidGenerator.new.generate_uuid
  end
end</pre>
<h2>Rules</h2>
<h3>Instantiation of new record</h3>
<p>Upon instantiating a new record, the declared default values are filled into the record. You&#8217;ve already seen this in the above examples.</p>
<h3>Retrieval of existing record</h3>
<p>Upon retrieving an existing record, the declared default values are <em>not</em> filled into the record. Consider the example with the UUID:</p>
<pre>user = User.create
user.uuid   # =&gt; "529c91b8bbd3e..."

user = User.find(user.id)
# UUID remains unchanged because it's retrieved from the database!
user.uuid   # =&gt; "529c91b8bbd3e..."</pre>
<h3>Mass-assignment</h3>
<p>If a certain attribute is being assigned via the model constructor&#8217;s mass-assignment argument, that the default value for that attribute will <em>not</em> be filled in:</p>
<pre>user = User.new(:uuid =&gt; "hello")
user.uuid   # =&gt; "hello"</pre>
<p>However, if that attribute is protected by <code>attr_protected</code> or <code>attr_accessible</code>, then it will be filled in:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :name, 'Joe'
  attr_protected :name
end

user = User.new(:name =&gt; "Jane")
user.name   # =&gt; "Joe"</pre>
<h3>Inheritance</h3>
<p>Inheritance works as expected. All default values are inherited by the child<br />
class:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :name, 'Joe'
end

class SuperUser &lt; User
end

SuperUser.new.name   # =&gt; "Joe"</pre>
<h3>Attributes that aren&#8217;t database columns</h3>
<p><code>default_value_for</code> also works with attributes that aren&#8217;t database columns. It works with anything for which there&#8217;s an assignment method:</p>
<pre># Suppose that your 'users' table only has a 'name' column.
class User &lt; ActiveRecord::Base
  default_value_for :name, 'Joe'
  default_value_for :age, 20
  default_value_for :registering, true

  attr_accessor :age

  def registering=(value)
    @registering = true
  end
end

user = User.new
user.age    # =&gt; 20
user.instance_variable_get('@registering')    # =&gt; true</pre>
<h3>Caveats</h3>
<p>A conflict can occur if your model class overrides the &#8216;initialize&#8217; method, because this plugin overrides &#8216;initialize&#8217; as well to do its job.</p>
<pre>class User &lt; ActiveRecord::Base
  def initialize  # &lt;-- this constructor causes problems
    super(:name =&gt; 'Name cannot be changed in constructor')
  end
end</pre>
<p>We recommend you to alias chain your initialize method in models where you use <code>default_value_for</code>:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :age, 20

  def initialize_with_my_app
    initialize_without_my_app(:name =&gt; 'Name cannot be changed in constructor')
  end

  alias_method_chain :initialize, :my_app
end</pre>
<p>Also, stick with the following rules:</p>
<ul>
<li>There is no need to <code>alias_method_chain</code> your initialize method in models that don&#8217;t use <code>default_value_for</code>.</li>
<li>Make sure that <code>alias_method_chain</code> is called <b>after</b> the last <code>default_value_for</code> occurance.</li>
</ul>
<h2>When (not) to use default_value_for?</h2>
<p>You can also specify default values in the database schema. For example, you can specify a default value in a migration as follows:</p>
<pre>create_table :users do |t|
  t.string    :username,  :null =&gt; false, :default =&gt; 'default username'
  t.integer   :age,       :null =&gt; false, :default =&gt; 20
  t.timestamp :last_seen, :null =&gt; false, :default =&gt; Time.now
end</pre>
<p>This has the same effect as passing the default value as the second argument to <code>default_value_for</code>:</p>
<pre>user = User.new
user.username   # =&gt; 'default username'
user.age        # =&gt; 20
user.timestamp  # =&gt; Mon Sep 22 18:31:47 +0200 2008</pre>
<p>It&#8217;s recommended that you use this over <code>default_value_for</code> whenever possible.</p>
<p>However, it&#8217;s not possible to specify a schema default for serialized columns. With <code>default_value_for</code>, you can:</p>
<pre>class User &lt; ActiveRecord::Base
  serialize :color
  default_value_for :color, [255, 0, 0]
end</pre>
<p>And if schema defaults don&#8217;t provide the flexibility that you need, then <code>default_value_for</code> is the perfect choice. For example, with <code>default_value_for</code> you could specify a per-environment default:</p>
<pre>class User &lt; ActiveRecord::Base
  if RAILS_ENV == "development"
    default_value_for :is_admin, true
  end
end</pre>
<p>Or, as you&#8217;ve seen in an earlier example, you can use <code>default_value_for</code> to generate a default random UUID:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :uuid do
    UuidGenerator.new.generate_uuid
  end
end</pre>
<p>Or you could use it to generate a timestamp that&#8217;s relative to the time at which the record is instantiated:</p>
<pre>class User &lt; ActiveRecord::Base
  default_value_for :account_expires_at do
    3.years.from_now
  end
end

User.new.account_expires_at   # =&gt; Mon Sep 22 18:43:42 +0200 2008
sleep(2)
User.new.account_expires_at   # =&gt; Mon Sep 22 18:43:44 +0200 2008</pre>
<p>Finally, it&#8217;s also possible to specify a default via an association:</p>
<pre># Has columns: 'name' and 'default_price'
class SuperMarket &lt; ActiveRecord::Base
  has_many :products
end

# Has columns: 'name' and 'price'
class Product &lt; ActiveRecord::Base
  belongs_to :super_market

  default_value_for :price do |product|
    product.super_market.default_price
  end
end

super_market = SuperMarket.create(:name =&gt; 'Albert Zwijn', :default_price =&gt; 100)
soap = super_market.products.create(:name =&gt; 'Soap')
soap.price   # =&gt; 100</pre>
<h3>What about before_validate/before_save?</h3>
<p>True, <code>before_validate</code> and <code>before_save</code> does what we want if we&#8217;re only interested in filling in a default before saving. However, if one wants to be able to access the default value even before saving, then be prepared to write a lot of code. Suppose that we want to be able to access a new record&#8217;s UUID, even before it&#8217;s saved. We could end up with the following code:</p>
<pre># In the controller
def create
  @user = User.new(params[:user])
  @user.generate_uuid
  email_report_to_admin("#{@user.username} with UUID #{@user.uuid} created.")
  @user.save!
end

# Model
class User &lt; ActiveRecord::Base
  before_save :generate_uuid_if_necessary

  def generate_uuid
    self.uuid = ...
  end

  private
    def generate_uuid_if_necessary
      if uuid.blank?
        generate_uuid
      end
    end
end</pre>
<p>The need to manually call <code>generate_uuid</code> here is ugly, and one can easily forget to do that. Can we do better? Let&#8217;s see:</p>
<pre># Controller
def create
  @user = User.new(params[:user])
  email_report_to_admin("#{@user.username} with UUID #{@user.uuid} created.")
  @user.save!
end

# Model
class User &lt; ActiveRecord::Base
  before_save :generate_uuid_if_necessary

  def uuid
    value = read_attribute('uuid')
    if !value
      value = generate_uuid
      write_attribute('uuid', value)
    end
    value
  end

  # We need to override this too, otherwise User.new.attributes won't return
  # a default UUID value. I've never tested with User.create() so maybe we
  # need to override even more things.
  def attributes
    uuid
    super
  end

  private
    def generate_uuid_if_necessary
      uuid  # Reader method automatically generates UUID if it doesn't exist
    end
end</pre>
<p>That&#8217;s an awful lot of code. Using <code>default_value_for</code> is easier, don&#8217;t you think?</p>
<h3>What about other plugins?</h3>
<p>I&#8217;ve only been able to find 2 similar plugins:</p>
<ul>
<li>Default Value: <a href="http://agilewebdevelopment.com/plugins/default_value">http://agilewebdevelopment.com/plugins/default_value</a></li>
<li>ActiveRecord Defaults: <a href="http://agilewebdevelopment.com/plugins/activerecord_defaults">http://agilewebdevelopment.com/plugins/activerecord_defaults</a></li>
</ul>
<p><em>Default Value</em> appears to be unmaintained; its SVN link is broken. This leaves only <em>ActiveRecord Defaults</em>. However, it is semantically dubious, which leaves it wide open for corner cases. For example, it is not clearly specified what ActiveRecord Defaults will do when attributes are protected by <code>attr_protected</code> or <code>attr_accessible</code>. It is also not clearly specified what one is supposed to do if one needs a custom <code>initialize</code> method in the model.</p>
<p>I&#8217;ve taken my time to thoroughly document default_value_for&#8217;s behavior.</p>
<h2>Credits</h2>
<p>I&#8217;ve wanted such functionality for a while now and it baffled me that ActiveRecord doesn&#8217;t provide a clean way for me to specify default values. After reading <a href="http://groups.google.com/group/rubyonrails-core/browse_thread/thread/b509a2fe2b62ac5/3e8243fa1954a935">http://groups.google.com/group/rubyonrails-core/browse_thread/thread/b509a2fe2b62ac5/3e8243fa1954a935</a>, it became clear that someone needs to write a plugin. This is the result.</p>
<p>Thanks to Pratik Naik for providing the initial code snippet on which this plugin is based on: <a href="http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model">http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model</a></p>
<p>If you like this plugin, then please <a href="http://www.modrails.com/enterprise.html">consider donating</a> and/or recommending us:</p>
<table class="wwr">
<tr>
<td>
<a href="http://www.workingwithrails.com/person/11402-hongli-lai"><img src="http://workingwithrails.com/images/tools/compact-small.jpg"/> Hongli Lai</a>
</td>
<td>
<a href="http://www.workingwithrails.com/person/12429-ninh-bui"><img src="http://workingwithrails.com/images/tools/compact-small.jpg"/> Ninh Bui</a>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2008/10/03/47/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

