<?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>Rails on the Run &#187; activeRecord</title>
	<atom:link href="http://railsontherun.com/tag/activerecord/feed/" rel="self" type="application/rss+xml" />
	<link>http://railsontherun.com</link>
	<description>Rails experiments by Matt Aimonetti</description>
	<lastBuildDate>Tue, 23 Feb 2010 07:28:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Ambition, why should you care?</title>
		<link>http://railsontherun.com/2007/09/16/ambition-why-should-you-care/</link>
		<comments>http://railsontherun.com/2007/09/16/ambition-why-should-you-care/#comments</comments>
		<pubDate>Sun, 16 Sep 2007 01:51:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[ambition]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/09/24/ambition-why-should-you-care</guid>
		<description><![CDATA[
By now, you should have heard about ambition if not read the latest post from the author.
Ambition has a simple goal: making you stop writing SQL in your queries and only stick to Ruby. (who cares if you use ActiveRecord, Sequel, DataMapper or another ORM)
I&#8217;m so used to the ActiveRecord way of querying the database [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://errtheblog.com/static/images/ambition-tower.png" alt="ambition"/></p>
<p>By now, you should have heard about <a href="http://errtheblog.com/post/10722">ambition</a> if not <a href="http://errtheblog.com/post/11998">read the latest post from the author</a>.</p>
<p><strong>Ambition has a simple goal: making you stop writing SQL in your queries and only stick to Ruby. (who cares if you use ActiveRecord, Sequel, DataMapper or another ORM)</strong></p>
<p>I&#8217;m so used to the ActiveRecord way of querying the database that I was not fully convinced that Ambition would help me in my daily tasks. I still gave it a try: </p>
<h2>Testing Ambition</h2>
<pre><code>$ sudo gem install ambition -y
</code></pre>
<p>Started my console</p>
<pre><code>$ script/console
</code></pre>
<p>and required Ambition</p>
<pre><code>require 'ambition'
</code></pre>
<p>I started by doing a query the AR way:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"> <span class="co">Photo</span>.find(<span class="sy">:all</span>, <span class="sy">:conditions</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">photos.title IS NULL AND photos.width &gt; 250 <tt>
</tt>AND photos.height &gt; 200 AND users.name = 'test'</span><span class="dl">&quot;</span></span>, <span class="sy">:include</span> =&gt; <span class="sy">:user</span>) </pre>
</td>
</tr>
</table>
<p>And I converted it into an Ambition call:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.width &gt; <span class="i">250</span> &amp;&amp; p.height &gt; <span class="i">200</span>  &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.entries</pre>
</td>
</tr>
</table>
<p>145 vs 102 keystrokes. 30% less typing with Ambition! I don&#8217;t know about you, but I REALLY prefer the Ruby only query, much cleaner and much &#8220;DRYer&#8221;. However, that&#8217;s not always true:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">Photo</span>.find_by_title(<span class="pc">nil</span>)</pre>
</td>
</tr>
</table>
<p>(24chars)<br />
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">Photo</span>.detect{|p| p.title == <span class="pc">nil</span>}</pre>
</td>
</tr>
</table>
<p> (32 chars)</p>
<p>But what&#8217;s going on behind the scene? Do we have the exact same SQL query sent to our DB?</p>
<p>Well, Ambition doesn&#8217;t generate any SQL, it uses AR to do so. You want to make sure Ambition is not messing with you, try that:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"> &gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.width &gt; <span class="i">250</span> &amp;&amp; p.height &gt; <span class="i">200</span>  &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.to_hash<tt>
</tt> =&gt; {<span class="sy">:conditions</span>=&gt;<span class="s"><span class="dl">&quot;</span><span class="k">(photos.`title` IS NULL AND (photos.`width` &gt; 250 AND (photos.`height` &gt; 200 AND users.name = 'test')))</span><span class="dl">&quot;</span></span>, <span class="sy">:include</span>=&gt;[<span class="sy">:user</span>]}</pre>
</td>
</tr>
</table>
<p>That&#8217;s pretty hot. Especially when you have to use eager loading! </p>
<p>Obviously you can still do stuff like that:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.width &gt; <span class="i">250</span> &amp;&amp; p.height &gt; <span class="i">200</span>  &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.each <span class="r">do</span> |photo|<tt>
</tt> puts photo.filename<tt>
</tt><span class="r">end</span></pre>
</td>
</tr>
</table>
<p>(note the query will only be made once)</p>
<p>Another cool thing, is to do simple sorting:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.sort_by { |p| [p.created_at, -p.size] }</pre>
</td>
</tr>
</table>
<p>creates the following:    </p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">=&gt; {<span class="sy"> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder</span>=&gt;<span class="s"><span class="dl">&quot;</span><span class="k">photos.created_at, photos.size DESC</span><span class="dl">&quot;</span></span>, <span class="sy">:conditions</span>=&gt;<span class="s"><span class="dl">&quot;</span><span class="k">(photos.`title` IS NULL AND users.name = 'test')</span><span class="dl">&quot;</span></span>, <span class="sy">:include</span>=&gt;[<span class="sy">:user</span>]}</pre>
</td>
</tr>
</table>
<p>or    </p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT * FROM photos JOIN user WHERE (photos.`title` IS NULL AND users.name = 'test') ORDER BY photos.created_at, photos.size DESC</span><span class="dl">&quot;</span></span></pre>
</td>
</tr>
</table>
<p>That&#8217;s cool, and you can still sort on relationships:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> }.sort_by { |p| p.user.name }<tt>
</tt>=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT * FROM photos JOIN user WHERE photos.`title` IS NULL ORDER BY users.name</span><span class="dl">&quot;</span></span>&lt;<span class="rx"><span class="dl">/</span><span class="k">macro:code &gt;<tt>
</tt>    <tt>
</tt>Or directly on the model:<tt>
</tt><tt>
</tt>&lt;macro:code lang=&quot;ruby&quot;&gt;&gt;&gt; Photo.sort_by(&amp;:title)<tt>
</tt>=&gt; &quot;SELECT * FROM photos ORDER BY photos.title&quot;</span></span></pre>
</td>
</tr>
</table>
<p>To finish, another detail which makes Ambition a great library</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.any? {|p| p.title =~ <span class="rx"><span class="dl">/</span><span class="k">ambition</span><span class="dl">/</span></span> }<tt>
</tt>=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT count(*) AS count_all FROM photos WHERE (photos.`title` REGEXP 'ambition')</span><span class="dl">&quot;</span></span> <tt>
</tt>=&gt; <span class="pc">true</span></pre>
</td>
</tr>
</table>
<p>And if you were worried that it wouldn&#8217;t work with utf8, check this out:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.any? {|p| p.title == <span class="s"><span class="dl">'</span><span class="k">Ã©cole</span><span class="dl">'</span></span>}<tt>
</tt>=&gt; <span class="co">SET</span> <span class="co">NAMES</span> <span class="s"><span class="dl">'</span><span class="k">utf8</span><span class="dl">'</span></span><tt>
</tt>=&gt; <span class="co">SET</span> <span class="co">SQL_AUTO_IS_NULL</span>=<span class="i">0</span><tt>
</tt>=&gt; <span class="co">SHOW</span> <span class="co">FIELDS</span> <span class="co">FROM</span> photos<tt>
</tt>=&gt; <span class="co">SELECT</span> count(*) <span class="co">AS</span> count_all <span class="co">FROM</span> photos <span class="co">WHERE</span> (photos.`title<span class="sh"><span class="dl">`</span><span class="k"> = 'Ã©cole') <tt>
</tt>=&gt; false</span></span></pre>
</td>
</tr>
</table>
<h2>Limitations</h2>
<p>The only limitation I found in Ambition is that Ruby code won&#8217;t work in the block, for instance:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.created_at &lt; <span class="i">1</span>.week.ago &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.entries</pre>
</td>
</tr>
</table>
<p>won&#8217;t work at the moment. To inspect what&#8217;s going simply try:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.created_at &lt; <span class="i">1</span>.week.ago &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.to_sql<tt>
</tt>=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT * FROM photos JOIN user WHERE (photos.`title` IS NULL AND (photos.`created_at` &lt; 1.`week`.`ago` AND users.name = 'test'))</span><span class="dl">&quot;</span></span></pre>
</td>
</tr>
</table>
<p>You can see that <strong>photos.<code>created_at</code> &lt; 1.<code>week</code>.<code>ago</code></strong>  is the problem.</p>
<p>The recommended way to achieve the same result is to use variables:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; date = <span class="i">1</span>.week.ago<tt>
</tt>&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.created_at &lt; date &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.to_sql<tt>
</tt>=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT * FROM photos JOIN user WHERE (photos.`title` IS NULL AND (photos.`created_at` &lt; '2007-09-08 19:38:48' AND users.name = 'test'))</span><span class="dl">&quot;</span></span></pre>
</td>
</tr>
</table>
<p>However, note that method calls will work just fine:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">&gt;&gt; <span class="r">def</span> <span class="fu">time_now_please</span><tt>
</tt>&gt;&gt; <span class="co">Time</span>.now<tt>
</tt>&gt;&gt; <span class="r">end</span><tt>
</tt>    <tt>
</tt>&gt;&gt; <span class="co">Photo</span>.select {|p| p.title == <span class="pc">nil</span> &amp;&amp; p.created_at &lt; time_now_please &amp;&amp; p.user.name == <span class="s"><span class="dl">'</span><span class="k">test</span><span class="dl">'</span></span>}.to_sql<tt>
</tt>=&gt; <span class="s"><span class="dl">&quot;</span><span class="k">SELECT * FROM photos JOIN user WHERE (photos.`title` IS NULL AND (photos.`created_at` &lt; '2007-09-15 19:41:37' AND users.name = 'test'))</span><span class="dl">&quot;</span></span>   </pre>
</td>
</tr>
</table>
<h2>Conclusion</h2>
<p>For now, Ambition is still just wrapping ActiveRecord::Base#find but the plan is to actually generate SQL. Hopefully we&#8217;ll also be able to use Ruby code from within an Ambition block. Kickers methods are very interesting and could become a really nice way of speeding up your app and keep your code clean.</p>
<p>Ambition is a great query library, I think I&#8217;ll start using it whenever I have &#8220;find&#8221; calls with multiple conditions especially if my conditions are related to another model. However I still didn&#8217;t figure out how to use an inner join with Ambition.</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/09/16/ambition-why-should-you-care/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Globalite Major update</title>
		<link>http://railsontherun.com/2007/09/02/globalite-major-update/</link>
		<comments>http://railsontherun.com/2007/09/02/globalite-major-update/#comments</comments>
		<pubDate>Sun, 02 Sep 2007 22:21:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[globalite]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[simplified chinese]]></category>
		<category><![CDATA[traditional chinese]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/09/02/globalite-major-update</guid>
		<description><![CDATA[I&#8217;m glad to announce a major update of Globalite.
First off I&#8217;d like to thank all the translators who helped with this release. 


Globalite now support its first Asian language: Chinese!
Ivan Chang did an awesome job creating a localization file in Chinese for Taiwan, Hong Kong and Main Land China. I&#8217;m really glad thinking that Globalite [...]]]></description>
			<content:encoded><![CDATA[<h2><em>I&#8217;m glad to announce a major update of Globalite.</em></h2>
<p>First off I&#8217;d like to thank all the translators who helped with this release. </p>
<ul>
<li>
<p>Globalite now support its <strong>first Asian language: Chinese!</strong><br />
Ivan Chang did an awesome job creating a localization file in Chinese for Taiwan, Hong Kong and Main Land China. I&#8217;m really glad thinking that Globalite will make the Rails experience much nicer for a lot of Chinese people.</p>
</li>
<li>
<p>Ivan also pushed me to add a new feature that people had asked about: a <strong>better ActiveRecord error message support</strong>.</p>
</li>
</ul>
<p>You know how Rails has a nice way of displaying your Model errors:</p>
<p><img src="http://farm2.static.flickr.com/1052/1306879608_e60431d214_o.png" alt="AR_error"/></p>
<p>Well, now that&#8217;s automatically translated in your locale. (as long as the new localization files are up to date. Feel free to contact me if you want to improve the locale file in your own language)</p>
<ul>
<li>I also added support for pluralization directly in the translation file. (pluralization doesn&#8217;t always make sense in some languages) I&#8217;m planning on adding a better Inflector support later on.</li>
</ul>
<p>for now, in your translation file simply use:</p>
<pre><code>horse_count: we have pluralize{{count}, horse} in the ranch
</code></pre>
<p>In your view use the localization with arguments to pass the count:</p>
<pre><code>&lt;%= :horse_count.l_with_args({:count =&gt; @horse.count}) %&gt;
</code></pre>
<p>See <a href="http://code.google.com/p/globalite/wiki/PluralizationSupport">the wiki</a> for more information about pluralization.</p>
<ul>
<li>Finally the <a href="http://globalite.googlecode.com/svn/sample/ui/">demo app</a> has been updated with an example of how to grab the acceptable locale from the header. (thanks to Emmanuel Bouton)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/09/02/globalite-major-update/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New version of Globalite is coming up</title>
		<link>http://railsontherun.com/2007/08/29/new-version-of-globalite-is-coming-up/</link>
		<comments>http://railsontherun.com/2007/08/29/new-version-of-globalite-is-coming-up/#comments</comments>
		<pubDate>Wed, 29 Aug 2007 14:10:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[globalite]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[translation]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/08/29/new-version-of-globalite-is-coming-up</guid>
		<description><![CDATA[I&#8217;m almost ready to update Globalite with 2 major changes:

Support for Chinese (Taiwan, Hong Kong and main land China) thanks to Ivan Chang
Better support for Active Record error messages in forms (based on contribution from Ivan)

I&#8217;m writing more tests and updating the sample app before releasing the updated version. It should be out in the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m almost ready to update Globalite with 2 major changes:</p>
<ul>
<li>Support for Chinese (Taiwan, Hong Kong and main land China) thanks to Ivan Chang</li>
<li>Better support for Active Record error messages in forms (based on contribution from Ivan)</li>
</ul>
<p>I&#8217;m writing more tests and updating the sample app before releasing the updated version. It should be out in the next few days.</p>
<p>[Globalite page @ Google Code](http://code.google.com/p/globalite/</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/08/29/new-version-of-globalite-is-coming-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>note to myself</title>
		<link>http://railsontherun.com/2007/05/11/note-to-myself/</link>
		<comments>http://railsontherun.com/2007/05/11/note-to-myself/#comments</comments>
		<pubDate>Fri, 11 May 2007 18:11:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[distinct]]></category>
		<category><![CDATA[mapping]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[unique]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/05/11/note-to-myself</guid>
		<description><![CDATA[This morning I couldn&#8217;t remember how to get an array with only the unique properties of a Model attribute. For instance, I have a User model, and I want to retrieve the list of all my users&#8217; cities. I also don&#8217;t want to retrieve all the attributes and only the unique rows.
in my model:
def self.cities
 [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I couldn&#8217;t remember how to get an array with only the unique properties of a Model attribute. For instance, I have a User model, and I want to retrieve the list of all my users&#8217; cities. I also don&#8217;t want to retrieve all the attributes and only the unique rows.</p>
<p>in my model:</p>
<pre><code>def self.cities
    User.find(:all, :select =&gt; "DISTINCT city").map(&amp;:city)
end
</code></pre>
<p>Clean and simple, but for some reason I know I&#8217;ll forget and loose 5 minutes trying different things. </p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/05/11/note-to-myself/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating a legacy app to Rails Part II</title>
		<link>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/</link>
		<comments>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/#comments</comments>
		<pubDate>Mon, 02 Apr 2007 18:31:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/05/22/migrating-legacy-app-part-2</guid>
		<description><![CDATA[In part I I quickly explained what I had to do, my limitations and a potential solution to connect to a legacy database.
In this post I&#8217;ll try to go through setting up a plugin for migration and start using RSpec for developing the migration plugin.
What we want is to migrate sites using the legacy application [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.railsontherun.com/2007/3/30/migrating-legacy-app-part-1">part I</a> I quickly explained what I had to do, my limitations and a potential solution to connect to a legacy database.</p>
<p>In this post I&#8217;ll try to go through setting up a plugin for migration and start using <a href="http://rspec.rubyforge.org/">RSpec</a> for developing the migration plugin.</p>
<p>What we want is to migrate sites using the legacy application to our new Rails application. That means that new users won&#8217;t be be migrated. It therefore makes sense not to add the migrating logic to the main application but to create a plugin. (if you are not familiar with Rails plugins check this <a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">blog post from Geoffrey Grosenbach about plugins</a>)</p>
<p>Let&#8217;s create our plugin</p>
<pre><code>./script/generate plugin legacy_migration</code></pre>
<p>Rails should have generated something like that:</p>
<pre><code>legacy_migration
|-- init.rb
|-- install.rb
|-- uninstall.rb
|-- Rakefile
|-- README
|-- lib/
|   |-- legacy_migration.rb
|-- tasks/
|   |-- legacy_migration_tasks.rake
|-- test
|   |-- legacy_migration_test.rb</code></pre>
<p>Since we are going to use RSpec, we can remove the test folder and create a spec folder. In our spec folder, let&#8217;s add some subfolders to organize our files. Let&#8217;s create a fixtures folder to hold, a helpers folder, a migrate folder (we&#8217;ll use that to migrate our legacy database) and finally, a models folder.</p>
<p>Our plugin folder should look more or less like that:</p>
<pre><code>legacy_migration
|-- init.rb
|-- install.rb
|-- uninstall.rb
|-- Rakefile
|-- README
|-- lib/
|   |-- legacy_migration.rb
|-- tasks/
|   |-- legacy_migration_tasks.rake
|-- spec
|   |-- fixtures
|   |-- helpers
|   |-- migrate
|   |-- models</code></pre>
<p>Great, let&#8217;s get started and let&#8217;s create our first spec. We should probably start by migrating users so I&#8217;ll create a new spec in the spec/models folder called legacy_user_spec.rb and add the following code:</p>
<pre><code>require File.dirname(<i>FILE</i>) + '/../helpers/legacy_user_helper'
require File.dirname(<i>FILE</i>) + '/../helpers/spec_helper'</code></pre>
<pre><code>describe "a connection to the legacy application" do
  setup do
    @connection_status = LEGACY.connect
  end
end</code></pre>
<pre><code>it "should be connected to the legacy database" do
  @connection_status.current_database.should == ActiveRecord::Base.configurations<a href="'database'">'legacy'</a>

end</code></pre>
<p>Note that I&#8217;m using RSpec trunk/edge and I use &#8220;describe&#8221; instead of &#8220;context&#8221; and &#8220;it&#8221; instead of &#8220;specify&#8221;. For more information on how to run RSpec edge with TextMate read <a href="http://www.railsontherun.com/2007/3/30/rspec-textmate-bundle-edge">this previous post</a>.</p>
<p>If we look at the code above, we start by requiring 2 helpers, a general helper called spec_helper and a helper just for this spec called legacy_user_helper (we will obviously need to create them otherwise our spec will failed).</p>
<p>Then we start our first spec by describing a connection to the legacy application and we specify that it should be connected to the legacy database.</p>
<p>Here is our setup code:</p>
<pre><code>setup do
  @connection_status = LEGACY.connect
end</code></pre>
<p>What I want is to retrieve a connection status after I connect to our legacy application. To manage the connection to the legacy application we will create a <span class="caps">LEGACY</span> module. We will need to connect to many legacy applications/sites and our module should help us doing that.</p>
<p>Then we can read that our spec checks that we are connected to the legacy database.</p>
<pre><code>it "should be connected to the legacy database" do
  @connection_status.current_database.should == ActiveRecord::Base.configurations<a href="'database'">'legacy'</a>
end</code></pre>
<p>That means we want to compare the connection status to the &#8216;legacy&#8217; environment defined in the database.yml file.</p>
<p>We now need to get this spec to pass.</p>
<p>Let&#8217;s get started by adding a legacy environment to our database.yml and creating our <span class="caps">LEGACY</span> module in our legacy_migration.rb file.</p>
<p>Add the following to your database.yml</p>
<pre><code>legacy:
  adapter: mysql
  database: legacy
  username: root
  password:
  host: localhost</code></pre>
<p>Now, let&#8217;s create the <span class="caps">LEGACY</span> module in our legacy_migration.rb file</p>
<pre><code>
module LEGACY

  # Connect to a Legacy database.
  # Usage:
  # Manual connection: LEGACY.connect(:database => 'legacy-database', :adapter => 'mysql', :username => 'root', :password => '', :host => 'localhost')
  # Auto connection to the database.yml defined legacy DB: LEGACY.connect
  # Connection to any database available in database.yml LEGACY.connect('legacy_test')
  # Connect a class to a specific database: LEGACY.connect(LegacyInstaller, ActiveRecord::Base.configurations['legacy_installer'])
  def self.connect(spec = nil, opt_env = nil)
    case spec
      # Automatically connect to the legacy environment database defined in the database.yml
    when nil
      raise 'Legacy Database not defined' unless defined? ActiveRecord::Base.configurations['legacy']
      LegacyActiveRecord.establish_connection(ActiveRecord::Base.configurations['legacy'])
      # Return the connections status
      LegacyActiveRecord.connection
      # A connection's name from the database.yml can be passed
    when Symbol, String
      if configuration = ActiveRecord::Base.configurations[spec.to_s]
        LegacyActiveRecord.establish_connection(configuration)
      else
        raise "#{spec} database is not configured"
      end
      # Connect a Model to a specific Database
    when Class
      raise 'Environment connection not provided or nil' unless defined? opt_env || opt_env['database'] == nil
      if spec.connection.current_database == opt_env['database']
        spec.connection
      else
        spec.establish_connection(opt_env)
      end
      # An array can be passed to establish the connection
    else
      spec = spec.symbolize_keys
      unless spec.key?(:adapter) then raise "database configuration does not specify adapter" end
        adapter_method = "#{spec[:adapter]}_connection"
        LegacyActiveRecord.establish_connection(spec)
      end
    end
  end</code></pre>
<p>There we go, we have a really cool connect function, we can easily connect to the default legacy environment defined in the database.yml file, we can specify the connection settings, connect to another environment database and even connect one specific class/model to a specific environment. (that will useful since we have many databases). If we wanted to follow the <span class="caps">TDD</span> rules, I shouldn&#8217;t have written so much code&#8230; as a matter of fact, when I worked on this project I did not, but since I don&#8217;t have much time, I won&#8217;t go through the re-factoring steps.</p>
<p>One thing you might have noticed is that we establish a connection between LegacyActiveRecord and the legacy database. (instead of connecting ActiveRecord to the legacy database).</p>
<pre><code>LegacyActiveRecord.establish_connection(ActiveRecord::Base.configurations['legacy'])</code></pre>
<p>The problem is that we didn&#8217;t create the LegacyActiveRecord model yet. Let&#8217;s do that right away. Let&#8217;s add a new folder called models in our lib folder. In the models folder, let&#8217;s create a legacy_active_record.rb file and add the following code:</p>
<pre><code>class LegacyActiveRecord &lt; ActiveRecord::Base
  self.abstract_class = true
end</code></pre>
<p>Cool, now let&#8217;s have fun with our new module, fire the console (./script/console) and try <span class="caps">LEGACY</span>.connect<br />
Here is what we get back:</p>
<pre><code>
    &gt;&gt; <span class="caps">LEGACY</span>.connect
    =&gt; #<activeRecord::ConnectionAdapters::MysqlAdapter:0x32a09d8 @runtime=0.000155925750732422, @config={:password=>nil, :database=&gt;&#8221;legacy&#8221;, :allow_concurrency=&gt;false, :host=&gt;&#8221;localhost&#8221;, :username=&gt;&#8221;root&#8221;, :adapter=&gt;&#8221;mysql&#8221;}, @connection_options=[&#8220;localhost&#8221;, &#8220;root&#8221;, &#8221;&#8221;, &#8220;legacy&#8221;, nil, nil], [...]

</code></pre>
<p>let&#8217;s try to get the database we connected to:</p>
<pre><code>&gt;&gt;LEGACY.connect.current_database
    =&gt; &#8220;legacy&#8221;

</code></pre>
<p>Awesome, we can now get our LegacyActiveRecord model to connect to our legacy database and return the connections status. Let&#8217;s run our specs&#8230;&#8230;&#8230;.. they pass.</p>
<p>Sweet, we setup our migration plugin, got our first spec written, added the code needed to get the spec to pass, I think we are done with <span class="caps">PART 2</span> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Migrating a legacy app to Rails PART I:</title>
		<link>http://railsontherun.com/2007/03/30/migrating-legacy-app-part-1/</link>
		<comments>http://railsontherun.com/2007/03/30/migrating-legacy-app-part-1/#comments</comments>
		<pubDate>Fri, 30 Mar 2007 22:40:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[migrating]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/09/26/migrating-legacy-app-part-1</guid>
		<description><![CDATA[I recently started working on migrating an old PHP based application to a new sexy Rails app. The old model was kind of messy, the usual case of bloated, feature creep app written by many people without any standard conventions. 
Anyway, I have to migrate users and content from many sites using the legacy app.
Data [...]]]></description>
			<content:encoded><![CDATA[<p>I recently started working on migrating an old PHP based application to a new <em>sexy</em> Rails app. The old model was kind of messy, the usual case of bloated, <a href="http://en.wikipedia.org/wiki/Feature_creep">feature creep</a> app written by many people without any standard conventions. </p>
<p>Anyway, I have to migrate users and content from many sites using the legacy app.</p>
<h1>Data Structure</h1>
<p>Instead of having 1 code base and 1 database per site, we now only have 1 code base and 1 database for all sites on a server. </p>
<p>The legacy application had a minimum of 3 databases:<br />
    1. installer database (keeps track of site version, manage upgrades, list sites on a server)<br />
    2. central server database (keeps all the sites details such as billing address, location, contacts, licenses&#8230; )<br />
    3. site database (contains users, content, settings)</p>
<p>Our new application, on the other hand, is as mentioned earlier, very <em>sexy</em> and has a nice Model. It is also developed following the <a href="http://behaviour-driven.org/">Behaviour-Driven Development</a> principles using <a href="http://rspec.rubyforge.org/">RSpec</a>. The best way for me to migrate the legacy data is probably to develop a Rails Plugin with a set of <a href="http://www.martinfowler.com/articles/rake.html#RakeTasks">Rake Tasks</a> that I could use to migrate my sites automatically.</p>
<p>I therefore decided to start working on my migration plugin&#8230; using BDD, with RSpec edge&#8230;.</p>
<p>The first think I started thinking was: what should I test/spec? how am I access the pile of not organized content from the legacy sites? How am I connect nicely to each of the legacy sites?</p>
<h1>Model Connection</h1>
<p>First question by order of priority: how could I leverage the legacy Model by using ActiveRecord? </p>
<p>I could create a Legacy Model for each table and connect each of them directly to the legacy database. Sounds ok but that means a lot of connections, and every time I would need to access another site, I would have to reconnect all my legacy classes&#8230; I was sure there was a better solution&#8230; and I was right. After googling for a solution, I noticed that <a href="http://pragdave.pragprog.com">Dave Thomas</a> had already found a <a href="http://pragdave.pragprog.com/pragdave/2006/01/sharing_externa.html">solution</a> few months earlier: </p>
<pre><code>class LegacyBase &lt; ActiveRecord::Base
    establish_connection ...
  end

  class LegacyUser &lt; LegacyBase
     ...
  end

  class LegacyContent&lt; LegacyBase
    ...
  end
</code></pre>
<p>And as Dave explains in his post: </p>
<blockquote>
<p>&#8220;It turns out that Rails does just about everything lazily. That includes connecting to databases and reflecting on tables to extract the schema (needed to build the internals of the models). This improves performance, but it also makes this hack possible. In general, youâ€™d expect the LegacyBase class to map to a database table called legacy_base. It would, if we ever tried to use it to access data. But because we donâ€™t, and because Rails only reflects on the table the first time a data access occurs, we can safely create an ActiveRecord class with no underlying database table. This scheme lets me specify the legacy connection once, and share that connection between all my legacy models. Itâ€™s tidy, expressive, and saves resources.&#8221;    </p>
</blockquote>
<p>Great, I had a technical solution to nicely connect to a legacy database.</p>
<p><a href="http://www.railsontherun.com/2007/4/2/migrating-legacy-app-part-2">Go to Part 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/03/30/migrating-legacy-app-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

