<?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; merb</title>
	<atom:link href="http://railsontherun.com/tag/merb/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>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Rails and Merb core team working together</title>
		<link>http://railsontherun.com/2008/12/24/rails-and-merb-core-team-working-together/</link>
		<comments>http://railsontherun.com/2008/12/24/rails-and-merb-core-team-working-together/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 08:47:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/12/24/rails-and-merb-core-team-working-together</guid>
		<description><![CDATA[This is huge! While people still try to find some drama an in hypothetical war between rails and merb. The Rails team and the Merb team announced working together on a joined version of the 2 frameworks. This is so exciting, nobody believed it could ever happen (I personally, had my serious doubt). Yehuda had [...]]]></description>
			<content:encoded><![CDATA[<h3>This is huge!</h3>
<p><img class="alignright size-medium wp-image-385" title="surprise" src="http://merbist.com/wp-content/uploads/2008/12/surprise-296x300.jpg" alt="" width="296" height="300" /></p>
<p>While people still try to find some drama an in hypothetical war between rails and merb.</p>
<p>The Rails team and the Merb team announced working together on a joined version of the 2 frameworks. This is so exciting, nobody believed it could ever happen (I personally, had my serious doubt).</p>
<p>Yehuda had a great post laying down the plan and explaining things in details. Check out David’s post explaining why he wants us to work together and his vision of a better Ruby world.</p>
<p>I have to say that I have been impressed by the Rails core team and especially David (DHH).</p>
<p>I’ve known David for few years now and we had long/heated discussions on topics like i18n/l10n for Rails. David is known to be a very opinionated person. But if you come up with the right arguments, he can be convinced and when that happens, he is willing to move forward and shake things up.</p>
<p>This merge is a concrete example that David and the rest of the Rails team cares about Rails and the Ruby community more than we usually give them credit for. As a unified team, we are going to change the way web development in Ruby is done!</p>
<p>But what does it mean for you?</p>
<p>I put together a FAQ video here is the transcript:</p>
<p>Hi, I’m Matt Aimonetti from the merb core team and as you might have heard, a big announcement was made earlier today.</p>
<p>I did this video to hopefully answer the questions you might have.</p>
<h3>Q: So what’s the big news?</h3>
<ul>
<li>merb and rails team will work together on the next version of their frameworks</li>
<li>merb 2.0 and rails 3.0 share the same common endpoint</li>
<li>we realized we now have the same objectives and agreed on all the key principles.</li>
<li>merb will provide Rails with agnosticism, modularity, improved performance and a public API.</li>
<li>The end product will be called Rails 3.0 but what real matters is that it’s a huge gain for the entire community.</li>
</ul>
<h3>Q: What??? I thought there was a war going on between Rails and merb, what happened?</h3>
<ul>
<li> There was no war between rails and merb</li>
<li> We created merb because rails was not fitting us</li>
<li> We wanted better performance, more choices/ more modularity and a Public API.</li>
<li> The Rails team now embraces these concepts and want Rails to follow them, so why not work together?</li>
</ul>
<h3>Q: Wait, does that mean that merb is dead?</h3>
<ul>
<li> Absolutely not!</li>
<li> merb development won’t stop, we are going to keep on releasing updates until rails 3.0</li>
<li> clear migration path, and upgrading to rails 3.0 will be as trivial as upgrading from rails 2.x to Rails 3.0</li>
</ul>
<h3>Q: What does the timeline look like?</h3>
<p>We just started getting together and discuss the technical details. We are shooting for a release at RailsConf 2009. However it’s hard to estimate this kind of things so again, that’s just an estimate <img class="wp-smiley" src="http://merbist.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" /></p>
<h3>Q: I just started a merb project, so what now?</h3>
<p>I’m sure you had valid reasons to use merb, you needed modularity, performance and a solid API.</p>
<p>Keep on using Merb, we won’t let you down. The good news is that the next version of merb (rails 3.0) will be even awesomer!</p>
<h3>Q: What about my client who was looking at using merb for his new project?</h3>
<p>If your client is going to be using merb for valid reasons (and not, just because it’s not rails) he should still use merb, but with the full understanding that he/she will end up using Rails in 6 months or so. Again, Rails 3.0 will have what pushed you to use merb.</p>
<h3>Q: I’ve been involved with the merb-book, what will happen with this project?</h3>
<ul>
<li> rails 3.0 won’t get released right away</li>
<li> still need awesome documentation</li>
<li> if we look at rails 3.0 as merb 2.0, we can easily imagine how the current work can be extended to the new version.</li>
<li> rails team will also include an evangelism team which I will be part of, so will be able to focus more on projects like the book.</li>
</ul>
<h3>Q: I’ve been working on a merb plugin, what should I do?</h3>
<p>Keep working on it! We’ll assist you with the migration process and the new solid API.</p>
<h3>Q: What if I still have questions?</h3>
<p>Come talk with me, or any members from the new team. We’ll be open to hear your questions, worries, frustrations.</p>
<p>merb always valued its developers and we will continue to do so but at a bigger scale.</p>
<hr />Concretely, nothing changes for Merb users. People loving Merb should not worry. The way you build merb apps won’t change until merb2.0/rails3.0. We will still work on your favorite framework and improve it.</p>
<p>Lori Holden worked on merb_sequel and we should release a 1.0 release of the plugin in a few days.</p>
<p>I’m sure this news comes as a shock for many of you, but try to not see Rails 3.0 as the way Rails is right now. Imagine a version of Rails with true modularity and agnosticism (sequel, DM and AR will still be supported) and the same type of performance as what you get with Merb. In other words, the rails world is about to discover the power of merb!</p>
<p>Here is what Yehuda explicitly says in his blog post:</p>
<ul>
<li>Rails will become more modular, starting with a rails-core, and including the ability to opt in or out of specific components. [...]</li>
<li>We will port all of our performance improvements into Rails. This includes architectural decisions that are big performance wins.[..]</li>
<li>As of Rails 3, Rails will have a defined public API with a test suite for that API. [..]</li>
<li>Rails will still ship with the “stack” version as the default (just as Merb does since 1.0), but the goal is to make it easy to do with Rails what people do with Merb today.</li>
<li>Rails will be modified to more easily support DataMapper or Sequel as first-class ORMs. [..]</li>
<li>Rails will continue their recent embrace of Rack, which [..] will improve the state of modular, sharable logic between applications.</li>
<li>In general, we will take a look at features in Merb that are not in Rails (the most obvious example is the more robust router) and find a way to bring them into Rails.</li>
</ul>
<h2>Personal perspective</h2>
<p>I’m personally really excited about this opportunity. I had a hard time believing that we could work together but I was proved wrong. We have many challenges in front of us, but watching the two teams working together is very reassuring.</p>
<p>I’m also glad to see that we will have a Rails Evangelism team that I will be part of. I strongly believe that one of the many reasons why merb has been so successful is because we work and listen to our community. We have put a tremendous amount of energy trying to understand what you guys need and what you like and dislike. In return, we saw many people working hard on the wiki and the merb-book.</p>
<p>Can you imagine doing that with almost 4 Million Rails developers?</p>
<p>I’m also looking forward to working with a team and reaching to even more people.</p>
<h2>Other news related to the merge:</h2>
<ul>
<li>The RubyOnRails website will keep a trace of this historical moment: <a href="http://rubyonrails.org/merb" target="_blank">http://rubyonrails.org/merb</a></li>
<li>The <a href="http://merbclass.com/" target="_blank">merb training scheduled for Jan 19-21</a> in partnership with <a href="http://integrumtech.com/" target="_blank">Integrum</a> will still take place, and if you want to get a head start and learn about the things that will make Rails 3.0 totally kick ass, I’d suggest you join us.</li>
</ul>
<p>If you have any questions, or if you want me to publicly answer questions on your blog please contact me. I’ll do my best to get back to everyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/12/24/rails-and-merb-core-team-working-together/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MerbCamp 2008 SanDiego</title>
		<link>http://railsontherun.com/2008/09/16/merbcamp-2008-sandiego/</link>
		<comments>http://railsontherun.com/2008/09/16/merbcamp-2008-sandiego/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 06:27:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[merbcamp]]></category>
		<category><![CDATA[san diego]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/09/16/merbcamp-2008-sandiego</guid>
		<description><![CDATA[That&#8217;s now finally official, MerbCamp 2008 registration are open! What an exciting time! History To understand why I&#8217;m excited, we need to go back few months back. Merb was first released by Ezra has an alternative tool to handle file uploads. Merb came to reality because Ezra needed something fast, light and flexible to handle [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://merbivore.com/img/merbcamp_badge_200.gif" alt="merbcamp"/></p>
<p>That&#8217;s now finally <a href="http://www.reuters.com/article/pressRelease/idUS113181+09-Sep-2008+PRN20080909">official</a>, <a href="http://merbcamp.com">MerbCamp</a> 2008 <a href="http://merbcamp.com/#registration">registration</a> are open! What an exciting time! </p>
<h2>History</h2>
<p>To understand why I&#8217;m excited, we need to go back few months back. Merb was first released by <a href="http://brainspl.at/">Ezra</a> has an alternative tool to handle file uploads. Merb came to reality because Ezra needed something fast, light and flexible to handle something that, let&#8217;s be frank about it, Rails had a hard time dealing with. Rails was king but was not as popular as now. Merb started as a simple Mongrel handler, in other words an alternative for small, light limited actions. Most people started using Merb simply to handle uploads. But as few cool kids started using Merb, they thought, hey, this thing is super fast, maybe I can use it to build small standalone apps. After all, hardcore developers don&#8217;t need &#8220;cool ajax helpers&#8221; and form builders to create a simple site. [Geoffrey Grosenback]() aka topfunky even proudly used Merb to reduild his site!<br />
That was just enough to convince me to start using Merb back at version 0.3.4. </p>
<p>I was an active Rails user and contributor. Having to use a bare bone Ruby web framework was quite refreshing however the lack of testing framework was a real show stopper <img src='http://railsontherun.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  (Being hooked up on RSpec by <a href="http://joshknowles.com">Josh Knowles</a> I ended up only writing a small portion of a Rails app with Merb 0.3.x (uploader backend).)</p>
<p>Quite quickly Merb&#8217;s philosophy changed and switched. The Mongrel handler framework started dreaming of becoming an alternative to Rails. Merb took the best from Rails but targeted another audience: the Ruby hackers living on the edge.<br />
Merb prides itself in being less opinionated than Rails(that can be argued tho), ORM agnostic (supporting ActiveRecord, Sequel and DataMapper), Javascript framework agnostic and truly modular. People like <a href="http://yehudakatz.com">Yehuda Katz</a>, <a href="http://merb.lighthouseapp.com/users/10354">Michael Klishin aka antares</a> got involved, as more contributors joined the effort, rules were enforced to make sure the framework would be as fast as possible and easy to extend without monkey patching. (ohh and fully tested using RSpec <img src='http://railsontherun.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><a href="http://engineyard.com">Engine Yard</a> decided to support the development effort and helped with Merb&#8217;s major rewrite (0.9 versions). Today, Merb is divided in 3 repositories, merb-core, merb-more and merb-plugins. By letting developers only choose what they want to use and by following a principle of isolation with private/public APIs, I believe Merb is today the most flexible yet powerful Ruby framework available.<br />
Furthermore, even though many people don&#8217;t understand the purpose of rewriting a &#8220;new Rails&#8221; from scratch, the reality is that many progress made by the merb team were ported back to Rails and inspired others (DataMapper for instance)! </p>
<p>Anyway, this is not a sale&#8217;s speech and I&#8217;m not trying to convince you to use Merb. My point is that Merb is finally coming to a point where the public API is stable and where one would find most tools he needs to build production ready applications.<br />
And, that&#8217;s basically a long sum up explaining why I wanted to organize something special to celebrate the 1.0 release and to create more awareness around Merb&#8217;s awesomeness!</p>
<h2>The Team behind MerbCamp</h2>
<p>I started getting involved with the SDRuby community a couple of years ago. As I got to know more people I realized that many people lead by <a href="http://mokolabs.com">Patrick Crowley</a> (leader of SDRuby and one of the organizers of SD BarCamp) had the desire to organize a local Ruby conf/camp. </p>
<p>At the same time, while I was working daily with Merb and contributing back to Merb&#8217;s code, many other SDRuby fellows were also getting really excited about Merb (<a href="http://notch8.com">Rob Kaufman</a>, <a href="http://">Ryan Felton</a> to mention a few).</p>
<p>Seeing the opportunity to host the very first Merb event in San Diego (host of RubyConf 2005!) I chatted with <a href="http://yehudakatz.com">yehuda</a> and the rest of the merb team. All the merb people were really excited, Leah Sibler from <a href="http://engineyard.com">Engine Yard</a> even offered her expertise to organize such an event (she&#8217;s totally awesome at planning/running conferences).</p>
<p>However, setting up such an event isn&#8217;t something one can do on his own. Before promising anything, I checked that Rubyists from San Diego would be interested and would help. In no time, I got a lot of people offering to help. </p>
<p>The key thing for me was to get someone with a good experience in organizing conferences. A person with resources and contacts. The only person I knew in San Diego who would be good enough to do that was <a href="http://mokolabs.com">Patrick Crowley</a>. We had a quick chat Patrick and I and it turned out that Patrick was very excited about organizing the very first MerbCamp in his town.<br />
Patrick quickly got a team together who agreed on working on the project. We got back to the Merb team and sealed the deal.</p>
<p>Patrick even found the <a href="http://www.calit2.net/">awesome venue</a> that many other cities will envy us! He&#8217;s been running the show, running here and there, making phone calls to make sure registration would open on time, setup the website etc&#8230;. Thanks Patrick!</p>
<h2>The Conf</h2>
<p>MerbCamp will be an hybrid between a BarCamp, a conference and an unconference. When the organization team got together, we all agreed that what we like the most during conferences is networking. We certainly also enjoy some good talks and definitely enjoyed the hack-room during the last Rails Conf.  We therefore decided to organize a conf  <em>*we</em>* would love to go.</p>
<ul>
<li>1 scheduled track with &#8220;official talks&#8221; to make sure we have some serious content and to motivate people to signup <img src='http://railsontherun.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>BBQ at the beach, because we live in San Diego and we love that! (plus, big open meals are the best way to network)</li>
<li>BarCamp type impromptu talks</li>
<li>hack-rooms so people can work together</li>
<li>friendly and small conference (we limited the amount of participants to 200)</li>
</ul>
<p>To conclude, I hope the &#8220;history&#8221; of MerbCamp 08 wasn&#8217;t too boring. People seem quite excited about this event, we even have guys in London who would get together to watch the talks via a webcam we are going to setup for them.<br />
We hope to see you there, if not, we hope you&#8217;ll organize your own conference and we will come have fun with you.</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/09/16/merbcamp-2008-sandiego/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>db fixtures replacement solution step by step</title>
		<link>http://railsontherun.com/2008/09/07/db-fixtures-replacement-solution-step-by-step/</link>
		<comments>http://railsontherun.com/2008/09/07/db-fixtures-replacement-solution-step-by-step/#comments</comments>
		<pubDate>Sun, 07 Sep 2008 16:06:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[datamapper]]></category>
		<category><![CDATA[factory_girl]]></category>
		<category><![CDATA[fixtures]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/09/07/db-fixtures-replacement-solution-step-by-step</guid>
		<description><![CDATA[Like most people who started with Rails a while back, I first loved Rails fixtures and ended up hating them (slow, a pain to maintain etc&#8230;). I went through different experiments, trying different existing libs, writing my own solutions etc&#8230; I wasn&#8217;t quite satisfied until I found factory_girl from thoughtbot. You might not feel the [...]]]></description>
			<content:encoded><![CDATA[<p>Like most people who started with Rails a while back, I first loved Rails fixtures and ended up hating them (slow, a pain to maintain etc&#8230;).</p>
<p>I went through different experiments, trying different existing libs, writing my own solutions etc&#8230; I wasn&#8217;t quite satisfied until I found <a href="http://github.com/thoughtbot/factory_girl">factory_girl</a> from <a href="http://www.thoughtbot.com/">thoughtbot</a>.</p>
<p>You might not feel the need for a decent fixtures solution if you do a lot of mocking/stubbing, but I recently came back from my &#8220;mock everything you can outside of models&#8221; approach and I&#8217;m getting closer to the <a href="http://snipr.com/3nwry">mock roles, not objects</a> approach. So, I&#8217;m loosing my model/controller testing separation but I&#8217;m gaining by not having to maintain &#8220;dumb mocks&#8221; which don&#8217;t always represent the real API behind. I mean, how many times did I change a Model, messing up my app but all my specs were still passing. Anyway, that&#8217;s a long discussion, which will be covered by <a href="http://yehudakatz.com/">wycats</a> during <a href="http://merbcamp.com">merbcamp</a></p>
<p>So here is a simple example of how I use <a href="http://github.com/thoughtbot/factory_girl">factory girl</a> in a Merb + DataMapper app. (you can do the same in a Rails app, there is <strong>nothing</strong> specific to Merb in factory_girl).</p>
<ul>
<li>I. create an empty app, set the ORM etc&#8230;</li>
<li>II. git pull and install factory<em>girl from <a href="http://github.com/thoughtbot/factory_girl/tree/master">http://github.com/thoughtbot/factory</a></em><a href="http://github.com/thoughtbot/factory_girl/tree/master">girl/tree/master</a>. Or install thoughtbot-factory_girl gem using <a href="http://gems.github.com">GitHub gem server</a>.</li>
<li><strong>III.</strong> create a spec/factories.rb file. (You might prefer to create a folder called spec/factories and add a factory per model)</li>
<li><strong>IV.</strong> modify spec_helper.rb and add the following</li>
</ul>
<pre class="brush:ruby">
  require 'factory_girl'
  require File.dirname(__FILE__) + '/factories'
</pre>
<ul>
<li>V. write some specs against a Client model</li>
</ul>
<p><script src="http://gist.github.com/9276.js"></script></p>
<ul>
<li><strong>VI.</strong> Create the Model</li>
</ul>
<p><script src="http://gist.github.com/9277.js"></script></p>
<ul>
<li><strong>VII.</strong> create a factory</li>
</ul>
<p><script src="http://gist.github.com/9278.js"></script></p>
<ul>
<li>
<strong>IIX.</strong> run your specs</p>
<p><img src="http://img.skitch.com/20080907-tf8yy6fi82b23t78stqii3mpbe.jpg" alt="failing specs" />
</li>
<li>
<strong>IX.</strong> fix the model (note that I set <code>dependencies "dm-validations"</code> in my init.rb)
</li>
</ul>
<p><script src="http://gist.github.com/9279.js"></script></p>
<ul>
<li>X. run the specs
<p><img src="http://img.skitch.com/20080907-m7p2r6q1qau4k3qsmeadwu2tur.jpg" alt="passing specs" /></li>
<li><strong>XI.</strong> add more specs</li>
</ul>
<p><script src="http://gist.github.com/9264.js"></script></p>
<p>As you can see, Factory.build(:client) only creates a new instance of the Object, while Factory(:client) creates, saves and loads the instance.</p>
<ul>
<li><strong>XII.</strong> get them to pass</li>
</ul>
<p><script src="http://gist.github.com/9265.js"></script></p>
<p>Factory Girl makes fixtures simple and clean. Here is another example for creating associations:</p>
<p><script src="http://gist.github.com/9269.js"></script></p>
<p>Factory Girl also supports sequencing, check out FG <a href="http://github.com/thoughtbot/factory_girl">read me</a></p>
<h2>In conclusion, Factory Girl is a mature and solid factory solution which will take you less than 15 minutes to get used to. It will offer you loads of flexibility and less frustration than good old yaml fixtures. You can also use it with existing fixtures if you want to start using it in an existing app.</h2>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/09/07/db-fixtures-replacement-solution-step-by-step/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ruby developers don&#8217;t scale</title>
		<link>http://railsontherun.com/2008/08/27/ruby-developers-don-t-scale/</link>
		<comments>http://railsontherun.com/2008/08/27/ruby-developers-don-t-scale/#comments</comments>
		<pubDate>Wed, 27 Aug 2008 14:58:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[developers]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/08/27/ruby-developers-don-t-scale</guid>
		<description><![CDATA[Wow, it&#8217;s been a while since I blogged. With all the cool kids saying that spending time reading RSS feeds is overrated (see Defunkt&#8217;s keynote for instance) I even wonder if people will ever read this post! Anyways, I have been quite busy preparing courses for classes I gave to a bunch a great Engineers [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, it&#8217;s been a while since I blogged. With all the cool kids saying that spending time reading RSS feeds is overrated (see <a href="http://rubyhoedown2008.confreaks.com/08-chris-wanstrath-keynote.html">Defunkt&#8217;s keynote</a> for instance) I even wonder if people will ever read this post!</p>
<p>Anyways, I have been quite busy preparing courses for classes I gave to a bunch a great Engineers at one of the Fortune 100 companies based in San Diego. I was also planning my big vacation trip to Europe and wrapping up few projects.</p>
<p>However, during my exile overseas, I came to the conclusion that <strong>Rubyists don&#8217;t scale</strong>. Since Twitter became stable again, we don&#8217;t hear many people ranting about Rails not scaling anymore.  With one of my clients&#8217; app handling around <strong>7 million requests/day</strong> I can tell you <strong>Ruby/Merb do scale quite well</strong>! But ruby developers don&#8217;t seem to scale for some reason.</p>
<p>Maybe saying that we(Rubyists) don&#8217;t scale isn&#8217;t technically correct but that&#8217;s basically what one of my client told me.</p>
<p>Let&#8217;s go back in time a little bit and follow my client who we will call clientX. </p>
<ul>
<li>ClientX has a <strong>great concept</strong> and wants to conquer the internet.</li>
<li>ClientX hears that <strong>Rails is the way to go</strong>.</li>
<li>ClientX hires a contractor/mercenary/freelancer/guns for hire/<strong>consultant</strong> (aka Me)</li>
<li>
<p>Me builds a <strong>killer app</strong> using <strong>Merb</strong> (killing framework)</p>
</li>
<li>
<p>ClientX raises loads of <strong>$$$</strong></p>
</li>
<li>
<p>ClientX <strong>wants to hire a team</strong> because Me doesn&#8217;t want to become a FTE</p>
</li>
<li>ClientX and Me <strong>look for Rubyists</strong> wanting to relocate and get a decent salary</li>
<li>
<p>ClientX <em>*can&#8217;t find someone</em> they consider good enough and who would accept their package</p>
</li>
<li>
<p>Many <strong>JAVA guys are available</strong> on location and accept lower packages</p>
</li>
<li><strong>Ruby app gets ported over to JAVA</strong></li>
<li><strong>Me sad</strong> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </li>
</ul>
<p>So is it really the Rubyists&#8217; fault if we don&#8217;t want to relocate and only accept higher packages? Should I blame <a href="http://blog.obiefernandez.com/">Obie</a> for telling people to charge more and teaching how to <a href="http://rubyhoedown2008.confreaks.com/07-obie-fernandez-do-the-hustle.html">hustle</a>? Or should we just tell clients that it&#8217;s time to get used to working remotely?</p>
<p>Honestly, I don&#8217;t think any of the above explanations are valid. Ruby is the new/hot technology and very few people have the skills and experience to lead major projects. These people make a good living and enjoy their &#8220;freedom&#8221; and dream of building their own products. Most of them/us value their work environment, family and are reluctant to move.</p>
<p><img src="http://img.skitch.com/20080827-rwca7tfprhce6hw19uytfqx1bc.jpg" alt="scale"/></p>
<p>At the same time, companies do need people locally(at least a core team) and can&#8217;t always afford the cool kids. </p>
<p>ClientX, quite frustrated by the whole hiring process told me once: <strong>&#8220;you Ruby folks are too unavailable and difficult to work with! We need a committed team that actually cares about the company/product.&#8221;</strong></p>
<p>That hurts when you worked hard on a project and just can&#8217;t satisfy the client by finding guys willing to relocate and work for them. <strong>It gets even more painful when your code gets entirely ported over to JAVA!</strong></p>
<p>But at the same time I understand ClientX&#8217;s motivation, PHP guys are cheaper, JAVA guys are more available, why in the word did we go with Ruby and are now struggling finding people?</p>
<p>Once again, there is positive and negative side in everything, by choosing Ruby and a &#8220;great contractor&#8221; ClientX was able to <strong>catch up with the competition and even pass them in no time</strong>. They quickly raised good money and got everything they needed to become #1. I don&#8217;t believe it would have been possible to do the same thing so quickly with JAVA for instance. However choosing a cutting edge technology means you need to look harder for talented people.</p>
<p>It&#8217;s too bad the code gets rewritten in a different language but at the same time, I do my best to facilitate the process and to keep a good relation with my client. There was nothing personal in the decision, it&#8217;s just too bad we were not able to keep on using the latest/coolest/awesomess technology available <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>To finish on a positive note, here is the solution to scale your Ruby task force provided to you by the #caboose wisdom:</h2>
<p>Based on my conversations with other #caboosers who hire other devs, the word in the street is that you just need to get one or two great ruby guys (who will probably cost you a lot) and find a bunch of smart people to train. You&#8217;ll end up with an awesome team of scalable rubyists <img src='http://railsontherun.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/08/27/ruby-developers-don-t-scale/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>News update</title>
		<link>http://railsontherun.com/2008/06/18/news-update/</link>
		<comments>http://railsontherun.com/2008/06/18/news-update/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 01:40:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[conf]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/06/18/news-update</guid>
		<description><![CDATA[I realized I haven&#8217;t updated this blog in a while. Here is a quick update on what&#8217;s happened and on things to come: RailsConf 08. Great conference, probably my last Rails Conf though. I&#8217;ll be in Orlando for Ruby Conf 08 and I&#8217;ll focus on 1 or 2 local conferences (probably mountain west and another [...]]]></description>
			<content:encoded><![CDATA[<p>I realized I haven&#8217;t updated this blog in a while. Here is a quick update on what&#8217;s happened and on things to come:</p>
<ul>
<li>
<p><a href="http://en.oreilly.com/rails2008/public/content/home">RailsConf 08</a>. Great conference, probably my last Rails Conf though. I&#8217;ll be in Orlando for <a href="http://rubyconf.org/">Ruby Conf 08</a> and I&#8217;ll focus on 1 or 2 local conferences (probably <a href="http://mtnwestrubyconf.org/">mountain west</a> and another one).</p>
</li>
<li>
<p>MerbCamp 08 in San Diego this Fall organized by <a href="http://sdruby.com">SD Ruby</a>. Details are not finalized yet but <a href="http://yehudakatz.com/">Yehuda Katz</a> announced it during his Merb talk at RailsConf.</p>
</li>
<li>
<p>Moved this blog to a new <a href="http://joyent.com">Joyent accelerator</a> with git support and finally have the possibility to use Ambition! (planning on moving from Mephisto to <a href="http://crazycool.co.uk/2008/04/26/announcing-feather">Feather</a>)</p>
</li>
<li>
<p>Launched a client&#8217;s Merb app and getting around 3 million hits/day. Merb is just awesome. (more info when the client&#8217;s app gets out of beta)</p>
</li>
<li>
<p>I&#8217;ll join <a href="http://railsenvy.com/">Gregg Pollack</a> from <a href="http://railsenvy.com/">http://railsenvy.com/</a> during <a href="http://qcon.infoq.com">Qcon</a> and take part in the <a href="http://qcon.infoq.com/sanfrancisco-2008/tracks/show_track.jsp?trackOID=172">Ruby for the Enterprise</a> track. <a href="http://qcon.infoq.com/sanfrancisco-2008/speaker/Matt+Aimonetti">My talk</a> will focus on Merb usage in real life.</p>
</li>
<li>
<p>Renamed my github username, new repo url: <a href="http://github.com/mattetti">http://github.com/mattetti</a> (sorry about that)</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/06/18/news-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Avoid using metaprogramming (seriously!)</title>
		<link>http://railsontherun.com/2008/05/04/avoid-using-metaprogramming/</link>
		<comments>http://railsontherun.com/2008/05/04/avoid-using-metaprogramming/#comments</comments>
		<pubDate>Sun, 04 May 2008 08:29:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[speed]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/05/04/avoid-using-metaprogramming</guid>
		<description><![CDATA[Ruby is sexy, Ruby is cool and its metaprogramming potential offers some really cook features. However you might not realize that your cleverness is slowing down your code. Today I was working on cleaning up merb_helper a Merb plugin that brings a lot of the stuff Rails developers are used to. In Merb we aim [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby is sexy, Ruby is cool and its metaprogramming potential offers some really cook features. However you might not realize that your cleverness is slowing down your code.</p>
<p>Today I was working on cleaning up merb_helper a Merb plugin that brings a lot of the stuff Rails developers are used to. In Merb we aim for speed and try to avoid magic.</p>
<p>merb_plugin didn&#8217;t receive a lot of love from the main contributors but few features were added by different contributors and the code became hard to maintain.</p>
<p>Looking at the code I quickly found this bad boy:</p>
<p>(Old Merb Time DSL using metaprogramming)</p>
<pre class="brush:ruby">
module MetaTimeDSL

    {:second => 1,
     :minute => 60,
     :hour => 3600,
     :day => [24,:hours],
     :week => [7,:days],
     :month => [30,:days],
     :year => [364.25, :days]}.each do |meth, amount|
      define_method "m_#{meth}" do
        amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount
        self * amount
      end
      alias_method "m_#{meth}s".intern, "m_#{meth}"
    end

  end
  Numeric.send :include, MetaTimeDSL
</pre>
<p>The above code looks awful to me and I decided to rewrite it a way I thought would be more efficient:</p>
<pre class="brush:ruby">
 module TimeDSL

    def second
      self * 1
    end
    alias_method :seconds, :second

    def minute
      self * 60
    end
    alias_method :minutes, :minute

    def hour
      self * 3600
    end
    alias_method :hours, :hour

    def day
      self * 86400
    end
    alias_method :days, :day

    def week
      self * 604800
    end
    alias_method :weeks, :week

    def month
      self * 2592000
    end
    alias_method :months, :month

    def year
      self * 31471200
    end
    alias_method :years, :year

  end
  Numeric.send :include, TimeDSL
</pre>
<p>To make sure I was right, I run the following benchmarks:</p>
<pre class="brush:ruby">
require 'benchmark'
TIMES = (ARGV[0] || 100_000).to_i

Benchmark.bmbm do |x|

  x.report("metaprogramming 360.seconds") do
    TIMES.times do
      360.m_seconds
    end
  end

  x.report("no metaprogramming 360.hours") do
    TIMES.times do
      360.seconds
    end
  end

  x.report("metaprogramming 360.minutes") do
    TIMES.times do
      360.m_minutes
    end
  end

  x.report("no metaprogramming 360.minutes") do
    TIMES.times do
      360.minutes
    end
  end

  x.report("metaprogramming 360.hours") do
    TIMES.times do
      360.m_hours
    end
  end

  x.report("no metaprogramming 360.hours") do
    TIMES.times do
      360.hours
    end
  end

  x.report("metaprogramming 360.days") do
    TIMES.times do
      360.m_days
    end
  end

  x.report("no metaprogramming 360.days") do
    TIMES.times do
      360.days
    end
  end

  x.report("metaprogramming 360.weeks") do
    TIMES.times do
      360.m_weeks
    end
  end

  x.report("no metaprogramming 360.weeks") do
    TIMES.times do
      360.weeks
    end
  end

  x.report("metaprogramming 18.months") do
    TIMES.times do
      18.m_months
    end
  end

  x.report("no metaprogramming 18.months") do
    TIMES.times do
      18.months
    end
  end

  x.report("metaprogramming 7.years") do
    TIMES.times do
      7.m_years
    end
  end

  x.report("no metaprogramming 7.years") do
    TIMES.times do
      7.years
    end
  end

end

 Rehearsal ------------------------------------------------------------------
metaprogramming 360.seconds      0.130000   0.000000   0.130000 (  0.133164)
no metaprogramming 360.hours     0.050000   0.000000   0.050000 (  0.042655)
metaprogramming 360.minutes      0.130000   0.000000   0.130000 (  0.133327)
no metaprogramming 360.minutes   0.040000   0.000000   0.040000 (  0.042401)
metaprogramming 360.hours        0.140000   0.000000   0.140000 (  0.134312)
no metaprogramming 360.hours     0.040000   0.000000   0.040000 (  0.043125)
metaprogramming 360.days         0.130000   0.000000   0.130000 (  0.134949)
no metaprogramming 360.days      0.050000   0.000000   0.050000 (  0.043745)
metaprogramming 360.weeks        0.130000   0.000000   0.130000 (  0.135581)
no metaprogramming 360.weeks     0.050000   0.000000   0.050000 (  0.043544)
metaprogramming 18.months        0.130000   0.000000   0.130000 (  0.135234)
no metaprogramming 18.months     0.050000   0.000000   0.050000 (  0.044354)
metaprogramming 7.years          0.140000   0.000000   0.140000 (  0.144062)
no metaprogramming 7.years       0.050000   0.000000   0.050000 (  0.044392)
--------------------------------------------------------- total: 1.260000sec

                                     user     system      total        real
metaprogramming 360.seconds      0.130000   0.000000   0.130000 (  0.132567)
no metaprogramming 360.hours     0.040000   0.000000   0.040000 (  0.042777)
metaprogramming 360.minutes      0.140000   0.000000   0.140000 (  0.132554)
no metaprogramming 360.minutes   0.040000   0.000000   0.040000 (  0.043193)
metaprogramming 360.hours        0.130000   0.000000   0.130000 (  0.133027)
no metaprogramming 360.hours     0.050000   0.000000   0.050000 (  0.042613)
metaprogramming 360.days         0.130000   0.000000   0.130000 (  0.138637)
no metaprogramming 360.days      0.050000   0.000000   0.050000 (  0.043213)
metaprogramming 360.weeks        0.130000   0.000000   0.130000 (  0.134049)
no metaprogramming 360.weeks     0.040000   0.000000   0.040000 (  0.043713)
metaprogramming 18.months        0.140000   0.000000   0.140000 (  0.134941)
no metaprogramming 18.months     0.040000   0.000000   0.040000 (  0.043980)
metaprogramming 7.years          0.150000   0.000000   0.150000 (  0.143389)
no metaprogramming 7.years       0.040000   0.000000   0.040000 (  0.044585)
 0.136591)
</pre>
<p>The metaprogramming version of the same implementation is almost 3 times slower!</p>
<p>Moral of the story: be careful when using metaprogramming, you might end up slowing down your code considerably.</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/05/04/avoid-using-metaprogramming/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Merb tip &#8211; how to freeze a project?</title>
		<link>http://railsontherun.com/2008/04/15/merb-tip-how-to-freeze-a-project/</link>
		<comments>http://railsontherun.com/2008/04/15/merb-tip-how-to-freeze-a-project/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 07:42:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[freezer]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[merb-freezer]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/11/10/merb-tip-how-to-freeze-a-project</guid>
		<description><![CDATA[THIS CONTENT is OUTDATED and can&#8217;t be used with Merb 1.0 or more recent Merb doesn&#8217;t really have a core team per say. It&#8217;s actually managed the same way Rubinius is managed meaning that few people such as Ezra, Wycats and Ivey lead the development while many other contributors have commit rights to the different [...]]]></description>
			<content:encoded><![CDATA[<p><strong>THIS CONTENT is OUTDATED and can&#8217;t be used with Merb 1.0 or more recent</strong></p>
<p><a href="merbivore">Merb</a> doesn&#8217;t really have a core team per say. It&#8217;s actually managed the same way <a href="http://rubini.us">Rubinius</a> is managed meaning that few people such as <a href="http://github.com/ezmobius">Ezra</a>, <a href="http://github.com/wycats">Wycats</a> and <a href="http://github.com/ivey">Ivey</a> lead the development while many other contributors have commit rights to the different repos.</p>
<p>Patches are handled via <a href="http://github.com">GitHub pull Request</a> and <a href="http://merb.lighthouseapp.com/">LightHouse tickets</a>. Read the following <a href="http://merbivore.com/contribute.html">contribution documentation</a> for more info.</p>
<p><img src="http://www.music-lyrics-chord.com/cover/Vanilla_Ice_Cool_as_Ice.jpg" alt="vanilla ice"/></p>
<p>Anyway, I&#8217;ve been working on a <a href="http://github.com/wycats/merb-more">merb-more</a> gem called <a href="http://github.com/wycats/merb-more/tree/master/merb-freezer">merb-freezer</a>.</p>
<p>We don&#8217;t have a logo for the plugin yet so I picked a &#8220;cool&#8221; star from the late 80&#8242;s to represent.</p>
<p><em>Vanilla Ice!</em></p>
<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/Vp-is6S_b_g&amp;hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/Vp-is6S_b_g&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
<p>Right, so you might wonder what&#8217;s the connection between a <a href="http://en.wikipedia.org/wiki/Kitsch">kitsch</a> white rapper and a new <a href="merbivore">Merb</a> Gem? Not much, apart that they are both cool (or kinda cool).</p>
<p>Let&#8217;s forget about &#8220;ice ice Baby&#8221; and focus on <a href="http://github.com/wycats/merb-more/tree/master/merb-freezer">merb-freezer</a>.</p>
<p><a href="http://github.com/wycats/merb-more/tree/master/merb-freezer">merb-freezer</a> has a simple goal: let you &#8220;freeze&#8221; your application and run it without dependencies. </p>
<h2>Why would you want to freeze your app?</h2>
<p><em>(This is only valid for Merb 0.9.3 and 0.9.2 edge as of April 14)</em></p>
<ul>
<li>
<p>You might have multiple applications on the same server/slice/cluster. Different applications might require different versions of Merb or some other Merb gems.</p>
</li>
<li>
<p>You might work with a team of developers and want everyone to be using the same version of the gems.</p>
</li>
<li>
<p>You are using Merb Edge and want to make sure that your coworkers are developing/testing against the same revision.</p>
</li>
</ul>
<h2>How to freeze your app?</h2>
<p>First thing, in your init.rb file you need to require merb-freezer</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' }">require <span class="s"><span class="dl">'</span><span class="k">merb-freezer</span><span class="dl">'</span></span></pre>
</td>
</tr>
</table>
<p>Now that you required the plugin when you get new rake tasks:</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></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  rake freeze<span class="sy">:core</span>            <span class="c"># Freeze core from git://github.com/wycats/merb...</span><tt>
</tt>  rake freeze<span class="sy">:more</span>            <span class="c"># Freeze more from git://github.com/wycats/merb...</span><tt>
</tt>  rake freeze<span class="sy">:plugins</span>         <span class="c"># Freeze plugins from git://github.com/wycats/m...</span><tt>
</tt></pre>
</td>
</tr>
</table>
<p>The rake freeze tasks use by default git submodules to freeze the various components. That means that you need to have your project under git to use that feature. However, if you didn&#8217;t switch to git yet, do no worry, we have a plan B.</p>
<p>When you run the freeze tasks a framework directory is created at the root of the folder and the gems are checked out there.</p>
<p>Not a git user? We thought of you and added an option for you to use rubygems. </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' }"><tt>
</tt>  rake freeze<span class="sy">:core</span> <span class="co">MODE</span>=rubygems<tt>
</tt></pre>
</td>
</tr>
</table>
<p>When doing that, you are freezing the latest version available on the rubygems server or installed locally.<br />
Note that when using the default mode, you are pulling the latest version of Merb from the official git repo. If you want to do that using rubygems you will need to checkout the git repos locally and install the gems yourself before freezing them.</p>
<p>Also it&#8217;s worth noting that you can also do all of that manually, as long as you follow the same conventions you should be fine.</p>
<h2>How to use the freezing gems?</h2>
<p>If you are a Rails user, you might expect that Merb uses the frozen gems by default, at least that what I expected. Turns out, it&#8217;s not the case since Merb avoids too much magic and unless you ask for it, Merb will use the available system gems.</p>
<p>So how to start a frozen merb app? Easy enough:</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' }">frozen-merb</pre>
</td>
</tr>
</table>
<p>That&#8217;s it, you can uninstall merb-core from your system and as long as you froze merb-core, you can start your app.</p>
<h2>How to update a frozen app?</h2>
<p>simply re-freeze but with the UPDATE=true param</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' }"><tt>
</tt>  rake freeze<span class="sy">:core</span> <span class="co">UPDATE</span>=<span class="pc">true</span><tt>
</tt></pre>
</td>
</tr>
</table>
<p>This option works for in both modes (rubygems and git submodules).</p>
<h2>What&#8217;s next?</h2>
<p>I&#8217;d like to add a locking mechanism that would allow you to force your app to only run on specific versions of few gems. The main advantage of this approach is that you wouldn&#8217;t need to freeze files in your repo as long as you have the required versions on your machine. </p>
<p>I would also like to extend the freezer to let you use the submodules to freeze other gems.</p>
<p>Other suggestions? Found a bug? Want to submit a patch?  Leave me a comment or use <a href="http://merb.lighthouseapp.com/">the Merb LightHouse ticketing system</a></p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/04/15/merb-tip-how-to-freeze-a-project/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails or Merb, what&#8217;s best for you?</title>
		<link>http://railsontherun.com/2008/04/10/rails-or-merb-what-s-best-for-you/</link>
		<comments>http://railsontherun.com/2008/04/10/rails-or-merb-what-s-best-for-you/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 08:10:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/04/10/rails-or-merb-what-s-best-for-you</guid>
		<description><![CDATA[If you follow my blog, you already know what Merb is. I love Rails and I truly believe it has changed web development. At least it has changed the way I do web development. But Merb looks slick, apparently is way faster than Rails, and has less &#8220;fluff&#8221; and less magic. Now that we are [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://brainspl.at/louiecon.gif" alt=""/></p>
<p>If you follow my blog, you already know what <a href="http://merbivore.com">Merb</a> is.</p>
<p>I love Rails and I truly believe it has changed web development. At least it has changed the way I do web development. </p>
<p>But Merb looks slick, apparently is way faster than Rails, and has less &#8220;fluff&#8221; and less magic. </p>
<p>Now that we are getting really close to a Merb 1.0 (scheduled for Rails Conf &#8217;08) it&#8217;s time to evaluate if Merb is the good choice for some of my clients&#8217; projects.</p>
<p>However, according to Merb&#8217;s author, Ezra, at MountainWest RubyConf 2008, <a href="http://mwrc2008.confreaks.com/02zygmuntowicz.html">Rails will get you there faster</a>. In a client&#8217;s case, they don&#8217;t need to build a huge app but need a lot of speed and the ability to easily handle a heavy load right away without using caching. Also most of the traffic will go through an API so we won&#8217;t have to manage too many views.</p>
<h2>Let&#8217;s see how fast Merb really is.</h2>
<p>To test Merb&#8217;s speed, I built the very same prototype using Merb 0.9.2 and Rails Edge (pre 2.1). Both apps use ActiveRecord and are connected to a UTF8 MySQL database, both apps have exactly the same views. (Note that Merb would run way faster using DataMapper, but I don&#8217;t feel that DM 0.9x is production ready yet, also, using a rack handler would certainly be way faster but my goal was really to compare ActionPack vs Merb.)</p>
<p>Both apps use the same ActiveRecord class, their controllers are a bit different but basically do the same thing.</p>
<p>Here is what was tested:</p>
<ul>
<li>
<p>The Merb/Rails app should receive a GET request with a JSON object in the query. </p>
</li>
<li>
<p>The Merb/Rails app should route the request to a controller and pass the JSON object to an AR class.</p>
</li>
<li>
<p>The AR class should parse the JSON object (which contains an array of objects), extract each object, and try to find them in the database using one of the attributes. If the object isn&#8217;t found, it should be created, otherwise it should return the AR object. The amount of hits should be incremented by 1 and the object should be saved back to the database.</p>
</li>
<li>
<p>A simple HTML view should be rendered</p>
</li>
</ul>
<h2>Quick Merb benchmark</h2>
<p><img src="http://merbivore.com/img/header_logo.png" alt="merb"/></p>
<p>I setup Merb to run locally on my MacBook 2.16Ghz Core Duo 2, 2Gb Ram. To test the raw performance, Merb is started in production mode.</p>
<p>I then used httperf to make 10000 connections to the server at a rate of 500 (&#8211;rate=500 &#8211;send-buffer=4096 &#8211;recv-buffer=16384 &#8211;num-conns=10000 &#8211;num-calls=1)</p>
<p>Here are the results:</p>
<pre><code>Maximum connect burst length: 29
Total: connections 4377 requests 4221 replies 2932 test-duration 41.629 s
Connection rate: 105.1 conn/s (9.5 ms/conn, &lt;=1022 concurrent connections)
Connection time [ms]: min 41.0 avg 1920.4 max 35390.8 median 898.5 stddev 4887.3
Connection time [ms]: connect 2118.1
Connection length [replies/conn]: 1.000

Request rate: 101.4 req/s (9.9 ms/req)
Request size [B]: 321.0

*Reply rate [replies/s]: min 0.0 avg 73.3 max 143.0 stddev 65.8 (8 samples)*
Reply time [ms]: response 809.0 transfer 18.1
Reply size [B]: header 121.0 content 557.0 footer 0.0 (total 678.0)
*Reply status: 1xx=0 2xx=2932 3xx=0 4xx=0 5xx=0*

CPU time [s]: user 0.35 system 36.54 (user 0.8% system 87.8% total 88.6%)
Net I/O: 78.4 KB/s (0.6*10^6 bps)

Errors: total 7068 client-timo 0 socket-timo 0 connrefused 0 connreset 1445
Errors: fd-unavail 5623 addrunavail 0 ftab-full 0 other 0
</code></pre>
<p>What we care about is the reply rate/s. We have an average of <em>73.3 requests per second</em> with a standard deviation of 65.8 using 8 samples.</p>
<p>We also make sure that all the replies were successful. (status == 2xx)</p>
<p>I also checked the database, made sure my AR object was created and that the hits were increased. AR object hits: 2932, which matches the amount of replies reported by httperf.</p>
<p>We don&#8217;t care so much about the rest of the httperf. Let&#8217;s move on to the Rails benchmark.</p>
<hr/>
<h2>Quick Rails benchmark</h2>
<p><img src="http://www.rubyonrails.org/images/rails.png" alt="rails"/></p>
<p>Rails is set the same way, running locally in production mode, same httperf settings.</p>
<p>Here are the results:</p>
<pre><code>Maximum connect burst length: 44

Total: connections 2923 requests 2825 replies 1672 test-duration 37.418 s

Connection rate: 78.1 conn/s (12.8 ms/conn, &lt;=1022 concurrent connections)
Connection time [ms]: min 382.7 avg 5635.4 max 36384.5 median 1887.5 stddev 10103.1
Connection time [ms]: connect 3631.2
Connection length [replies/conn]: 1.000

Request rate: 75.5 req/s (13.2 ms/req)
Request size [B]: 319.0

*Reply rate [replies/s]: min 0.0 avg 43.4 max 75.2 stddev 30.8 (7 samples)*
Reply time [ms]: response 1568.1 transfer 36.7
Reply size [B]: header 471.0 content 581.0 footer 0.0 (total 1052.0)
*Reply status: 1xx=0 2xx=1672 3xx=0 4xx=0 5xx=0*

CPU time [s]: user 0.25 system 31.31 (user 0.7% system 83.7% total 84.4%)
Net I/O: 69.4 KB/s (0.6*10^6 bps)

DB hits: 1672
</code></pre>
<p>First thing, the database object was created properly and the hits incremented to 1672 which matches the amount of replies reported by httperf.</p>
<p>Then, we notice that on this test, we only got 7 samples, that&#8217;s more than enough though. The standard deviation is 30.8 which is better than Merb&#8217;s 65.8. That means that in our benchmarks, the reply speed difference in Merb&#8217;s requests was bigger than Rails&#8217;. Not a big deal, this is not a scientific test but it&#8217;s good to acknowledge it.</p>
<p>What we really care about is the average reply rate: 43.4</p>
<p>Let&#8217;s also note that all the replies had a 2xx status, so everything went well.</p>
<h2>Results</h2>
<p>Based on this really basic benchmark, my Merb app had an average reply rate of <em>73.3 requests per second</em> against Rails&#8217; <em>43.4 requests per second</em>.</p>
<p>That means that in this very specific case, </p>
<h2><em>Merb is 69% faster than Rails</em>!  Sexy! </h2>
<p>In other words, my Merb prototype could handle 69% more requests than the Rails prototype in the same amount of time.</p>
<p>I heard people reporting than Merb was 3 to 5 times faster than Rails. Honestly, it really depends on what you do. By using ActiveRecord on both prototypes, I limited the speed difference since AR is not multithread and therefore Merb can&#8217;t run as fast as it would using Sequel or DataMapper. By actually hitting the database on every single request, I also made sure to really compare ActionPack vs Merb.</p>
<h2>Conclusion</h2>
<p>The conclusion is simple, I recommended that my client go with Merb. Merb 1.0 is almost ready, the public API has been frozen. My client needs speed and simplicity. Using Merb I get exactly what I need and nothing more. Actually, we&#8217;ll probably increase the performance by writing a rack handler and bypassing the entire framework for API calls (that should be wicked fast!).  Also, as soon as DataMapper becomes production ready, we&#8217;ll switch to DM and should get way better performance!</p>
<p>Am I suggesting to give up Rails and switch to Merb?<br />
Absolutely not!  First off, Merb is a &#8220;lower level&#8221; framework. It requires a deeper understanding of Web Development in general and being more than just &#8216;acquainted&#8217; with the Ruby language. So, unless you are an advanced developer or have time to learn, I would suggest to keep on using Rails (start using Merb on personal projects, it&#8217;s a perfect way of learning).<br />
If you have a lot of views and/or use loads of AJAX, RJS, built-in helpers, you probably want to stick to Rails and start looking at how you can do all of that from scratch. By default Rails uses nasty helpers that create inline javascript, and is something you really want to avoid. RJS is fun, but it goes against Merb&#8217;s philosophy, so you need to make sure you can live without it (note that you can reproduce the same behavior in Merb rendering JS, it just requries more work). If you rely a lot of Rails plugins, you might want to delay your switch, Merb is pretty new and doesn&#8217;t have a mass-load of plugins yet.</p>
<p>Finally, Merb doesn&#8217;t have a lot of documentation and changed a lot when 0.9 got released. To understand how Merb works, you will need to go through the source code, specs, Google, and ask on the Merb IRC channel.</p>
<p>It turns out that in our case we have experienced developers, a great need for speed, not too many views and are following Merb&#8217;s development really closely . I honestly think it&#8217;s the best choice for my client and I&#8217;m excited they accepted to use Merb.</p>
<p>Merb is addressing different issues than Rails and doing it well. I think there is a bright future for Merb. And don&#8217;t even think that Rails is going away, that won&#8217;t happen anytime soon! </p>
<p>Recently, <a href="http://www.us.playstation.com/Corporate/About">Sony Playstation</a> even posted a <a href="https://www2.recruitingcenter.net/Clients/playstation/PublicJobs/controller.cfm?jbaction=JobProfile&amp;Job_Id=11424&amp;esid=az">job post</a> looking for a Rails/Merb developer. This is very promising for the Merb community!</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/04/10/rails-or-merb-what-s-best-for-you/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Merb tips II</title>
		<link>http://railsontherun.com/2008/04/08/merb-tips-2/</link>
		<comments>http://railsontherun.com/2008/04/08/merb-tips-2/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 02:11:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[logger]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[routes]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/11/10/merb-tips-2</guid>
		<description><![CDATA[* this content is now outdated and only applied to Merb 0.9* I the previous post I covered few useful tips for Merb 0.9. The good news is that Merb should get its wiki setup over the week end! Here is another batch of hopefully useful tips: In init.rb, you can define a dependency and [...]]]></description>
			<content:encoded><![CDATA[<p><em>* this content is now outdated and only applied to Merb 0.9</em>*</p>
<p>I the <a href="http://railsontherun.com/2008/4/5/merb-tips-1">previous post</a> I covered few useful tips for Merb 0.9. The good news is that Merb should get its wiki setup over the week end!</p>
<p>Here is another batch of hopefully useful tips:</p>
<ul>
<li>
<p>In init.rb, you can define a dependency and specify a version number: <em>dependency &#8220;merb_fu&#8221;, &#8220;>= 1.0&#8243;</em></p>
</li>
<li>
<p>If you want to run your application from a subdirectory, once again, in your init.rb file, add: <em>c[:path_prefix] = &#8220;/your_prefix&#8221;</em> <em>(note, that you can also do that in a specific environment file.)</em></p>
</li>
<li>
<p>You feel like limiting a route to a specific request such as a DELETE? In your router.rb file add the following:</p>
</li>
</ul>
<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' }"><tt>
</tt>  r.match(<span class="s"><span class="dl">&quot;</span><span class="k">/:bucket_id</span><span class="dl">&quot;</span></span>, <span class="sy">:method</span> =&gt; <span class="sy">:delete</span>).to(<span class="sy">:controller</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">buckets</span><span class="dl">&quot;</span></span>, <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">destroy</span><span class="dl">&quot;</span></span>)<tt>
</tt></pre>
</td>
</tr>
</table>
<ul>
<li>Since we are talking about routes, what about an iPhone only route?</li>
</ul>
<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' }"><tt>
</tt>  r.match(<span class="rx"><span class="dl">%r[</span><span class="k">^/(.+)</span><span class="dl">]</span></span>, <span class="sy">:user_agent</span> =&gt; <span class="rx"><span class="dl">/</span><span class="k">iPhone</span><span class="dl">/</span></span>).to(<span class="sy">:controller</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">mobile</span><span class="dl">&quot;</span></span>, <span class="sy">:title</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">Welcome Apple FanBoy</span><span class="dl">&quot;</span></span>, <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">show</span><span class="dl">&quot;</span></span>)<tt>
</tt></pre>
</td>
</tr>
</table>
<ul>
<li>what about an admin section for my blogposts?</li>
</ul>
<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></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  r.match(<span class="s"><span class="dl">'</span><span class="k">/admin</span><span class="dl">'</span></span>) <span class="r">do</span> |admin|<tt>
</tt>    admin.resources <span class="sy">:blogposts</span><tt>
</tt>  <span class="r">end</span><tt>
</tt></pre>
</td>
</tr>
</table>
<ul>
<li>To finish with the routes, look at the <a href="http://github.com/wycats/merb-core/tree/master/spec/public/router/special_spec.rb#L39-46">following merb-core spec</a></li>
</ul>
<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>8<tt>
</tt>9<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should allow you to restrict routes based on protocol</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    <span class="co">Merb</span>::<span class="co">Router</span>.prepare <span class="r">do</span> |r|<tt>
</tt>      r.match(<span class="sy">:protocol</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">http://</span><span class="dl">&quot;</span></span>).to(<span class="sy">:controller</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">foo</span><span class="dl">&quot;</span></span>, <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">bar</span><span class="dl">&quot;</span></span>)<tt>
</tt>      r.default_routes<tt>
</tt>    <span class="r">end</span><tt>
</tt>    route_to(<span class="s"><span class="dl">&quot;</span><span class="k">/foo/bar</span><span class="dl">&quot;</span></span>).should have_route(<span class="sy">:controller</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">foo</span><span class="dl">&quot;</span></span>, <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">bar</span><span class="dl">&quot;</span></span>)<tt>
</tt>    route_to(<span class="s"><span class="dl">&quot;</span><span class="k">/boo/hoo</span><span class="dl">&quot;</span></span>, <span class="sy">:protocol</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">https://</span><span class="dl">&quot;</span></span>).should have_route(<span class="sy">:controller</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">boo</span><span class="dl">&quot;</span></span>, <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">hoo</span><span class="dl">&quot;</span></span>)<tt>
</tt>  <span class="r">end</span><tt>
</tt></pre>
</td>
</tr>
</table>
<p>You can set custom routes to only work when connected via SSL, that&#8217;s just really nice!</p>
<ul>
<li>Other quick tip. <a href="http://railsontherun.com/2008/4/5/merb-tips-1">Last time</a> we saw how to install locally all the required gems. Well, you can also freeze merb by doing:</li>
</ul>
<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' }"><tt>
</tt>  merb-gen frozen-merb<tt>
</tt></pre>
</td>
</tr>
</table>
<ul>
<li>Another common IRC question, how do I use Merb&#8217;s logger. It&#8217;s really easy:</li>
</ul>
<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' }"><tt>
</tt>  <span class="co">Merb</span>.logger.info(<span class="s"><span class="dl">'</span><span class="k">our stuff</span><span class="dl">'</span></span>)<tt>
</tt></pre>
</td>
</tr>
</table>
<p>Where info is the debugging level you want to send your message to.</p>
<ul>
<li>Finally, today in IRC a Rails user asked how reset a session in Merb. Rails has a <em>reset_session</em> method that resets the session by clearing out all the objects stored within and initializing a new session object. Merb simply uses a hash to store sessions, so <em>session.clear</em> will do it <img src='http://railsontherun.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
</ul>
<p>Feel free to add a comment with your Merb tips or leave a question regarding something you can&#8217;t seem to be able to do with Merb.</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/04/08/merb-tips-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Merb tips I</title>
		<link>http://railsontherun.com/2008/04/05/merb-tips-1/</link>
		<comments>http://railsontherun.com/2008/04/05/merb-tips-1/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 05:59:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[logger]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/11/10/merb-tips-1</guid>
		<description><![CDATA[* this content is now outdated and only applied to Merb 0.9* I&#8217;m working on a post reporting a recent benchmark I did comparing Rails vs Merb performances for a client&#8217;s app. In the meantime, here are few tricks you might need when using Merb 0.9x In the init.rb file, uncomment and rename c[:session_id_key] (in [...]]]></description>
			<content:encoded><![CDATA[<p><em>* this content is now outdated and only applied to Merb 0.9</em>*</p>
<p>I&#8217;m working on a post reporting a recent benchmark I did comparing Rails vs Merb performances for a client&#8217;s app.</p>
<p>In the meantime, here are few tricks you might need when using Merb 0.9x</p>
<ol>
<li>
<p>In the init.rb file, uncomment and rename <em>c[:session_id_key]</em>  (in the Merb::Config.use block)</p>
</li>
<li>
<p>In the same block, add <em>c[:log_level] = :debug</em>  to set a log level</p>
</li>
<li>
<p>By default, Merb logs to STDOUT, to log to a file, in the config block add <em>c[:log_file] = Merb.log_path + &#8216;/development.log&#8217;</em>  (note that you need to create the file yourself, Merb won&#8217;t do that)</p>
</li>
<li>
<p>to save your gems locally, do: <em>sudo gem install gem_name -i gems</em></p>
</li>
<li>
<p>need basic HTTP auth? <a href="http://github.com/wycats/merb-core/tree/e690bb81bb550e58dad519712de050141b8552d8/lib/merb-core/controller/mixins/authentication.rb#L15-46">it&#8217;s now available in core</a></p>
</li>
<li>
<p>don&#8217;t forget to require any plugins, extra gems you need (such as <em>merb_helpers</em> or <em>merb-assets</em>)</p>
</li>
<li>
<p>don&#8217;t forget to select your ORM before using the generator( so your generated goodies will be adapted to your ORM)</p>
</li>
<li>
<p>routes are easy to use. In the console (merb -i) type <em>merb.show_routes</em> to see all your named routes</p>
</li>
<li>
<p>if you want to use link<em>to, install <a href="http://github.com/wycats/merb-plugins/tree/master/merb_assets">merb</em>assets</a></p>
</li>
<li>
<p>nested routes example:</p>
</li>
</ol>
<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' }"><tt>
</tt>  r.resources <span class="sy">:channels</span> <span class="r">do</span> |channels|<tt>
</tt>    channels.resources <span class="sy">:shows</span> <span class="r">do</span> |shows|<tt>
</tt>     shows.resources <span class="sy">:episodes</span><tt>
</tt>    <span class="r">end</span><tt>
</tt>   <span class="r">end</span><tt>
</tt></pre>
</td>
</tr>
</table>
<p>usage: </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></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  url(<span class="sy">:channel_shows</span>, <span class="sy">:channel_id</span> =&gt; channel)<tt>
</tt><tt>
</tt>  link_to h(channel.description), url(<span class="sy">:channel</span>, <span class="sy">:id</span> =&gt; channel)<tt>
</tt></pre>
</td>
</tr>
</table>
<p>That&#8217;s it for today <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In the meantime, check this <a href="http://mwrc2008.confreaks.com/02zygmuntowicz.html">Merb presentation by Ezra</a> and <a href="http://mwrc2008.confreaks.com/04katz.html">this DataMapper presentation by Wycats</a></p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/04/05/merb-tips-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

