Nick Sieger: Tag railsconfeurope2007 http://blog.nicksieger.com/articles/tag/railsconfeurope2007?tag=railsconfeurope2007 en-us 40 RailsConf Europe: Hydra <p><img src="/files/hydra.png" alt="Hydra" title="Hydra"/></p> <p>On September 19, Craig and I presented our <a href="http://blog.nicksieger.com/articles/2007/09/14/gig-speaking-at-railsconf-europe-2007">talk at RailsConf</a>, which appears to have been <a href="http://loudthinking.com/posts/11-sun-surprises-at-railsconf-europe-2007">well received</a>&#46; It went off mostly without a hitch, if it wasn&#8217;t for a couple of hiccups in the demos&#46; I apparently didn&#8217;t practice them enough, because a couple of critical steps were either missed or I did them out of order and confused myself&#46; But that&#8217;s ok, because I&#8217;m releasing the demo steps, source and slides here so you can try them out for yourself&#46;</p> <p>So, <a href="http://blog.nicksieger.com/files/RailsConfEurope-Hydra.zip">download the zip</a> and follow along&#46; The contents look like this:</p> <pre><code>1-active-resource-basics.txt 2-make-resourceful.txt 3-atom-roller.txt 4-service-chatter.txt RailsConfEurope-Hydra.pdf demo/ demo-baked/ </code></pre> <p>The demo steps are in the text files; I&#8217;d recommend going in the order specified&#46; It turns out the third isn&#8217;t really a demo but more of a code review, because it also requires you to have Roller set up and I&#8217;m not going into those details for now&#46; If you want to just run the demos, skip to <code>demo-baked</code>, the finished product&#46;</p> <p>For those of you who didn&#8217;t see the talk, here&#8217;s the basic message&#46;</p> <p>Look at your basic MVC Rails app&#46;</p> <p><img src="/files/single.png" alt="Single app" title="Single app"/></p> <p>Why not consider spliting it into two? ActiveResource allows you to access a RESTful resource in your Rails application like it was just another model&#46;</p> <p><img src="/files/double.png" alt="Double app" title="Double app"/></p> <p>This might seem like overkill for a simple application, but what if you had an e&#45;commerce application domain like this?</p> <p><img src="/files/ecomm.png" alt="E-Commerce app" title="E-Commerce app"/></p> <p>Splitting up your code into separate Rails applications encourages encapsulation, reduces potential coupling, and gives you more flexible deployment options&#46; Basing interactions upon REST and HTTP means that you can more easily mash up data or create caching strategies, given proper usage of ETags/Last&#45;Modified and/or cache&#45;control headers&#46; The great thing is that existing HTTP reverse proxies can be used without having to mix the caching code in with your application code&#46;</p> <p>In the application we&#8217;re building, we have a number components that are not Rails&#45;based&#46; To expose them to our environment, we&#8217;ve taken the strategy of exposing a simple REST web service for the component, and then it can be consumed by the other applications using ActiveResource&#46; The REST web service can either be implemented in the component&#8217;s native language/technology, or in some cases we&#8217;ve written a wrapper service in Rails since Rails makes it so easy to build REST interfaces&#46; In that case, Rails is pure integration &#45;&#45; RESTful glue&#46;</p> <p>The idiom that makes this all possible is the uniform interface&#46; In HTTP, this means addressability (each resource gets a unique URI) coupled with the HTTP method verbs HEAD, GET, POST, PUT, and DELETE&#46; Inside your Rails applications, it&#8217;s the ActiveRecord interface&#46; If you <a href="http://www.therailsway.com/2007/6/1/railsconf-recap-skinny-controllers">keep your controllers skinny</a>, you can boil the interface down to the following set of methods (in this case, for the prototypical blog post model):</p> <pre><code>Post.new/Post.create Post.find @post.save @post.update_attributes @post.errors @post.destroy </code></pre> <p>And in fact, this is precisely what ActiveResource provides, and it&#8217;s enabled by <a href="http://en.wikipedia.org/wiki/Duck_typing">duck&#45;typing</a>&#46; Walking through the demos illustrates this pretty well, as you&#8217;ll basically swap ActiveRecord for ActiveResource with no noticeable difference, all the way down to validation errors in the scaffolded forms (which I was unable to demo in the talk due to the hiccups)&#46;</p> <p>We&#8217;ve found that when you&#8217;re making RESTful web services, the controllers largely become boilerplate because of the uniform interface&#46; <a href="http://svn.hamptoncatlin.com/make_resourceful/trunk/"><code>make_resourceful</code></a> has been a boon in that regard, as the demos also show&#46; There are several plugins that help you DRY up your controllers (other approaches include <a href="http://plugins.ardes.com/doc/resources_controller/"><code>resources_controller</code></a>), so you have some choices there&#46;</p> <p>We mentioned some drawbacks in our experience with ActiveResource, which have largely been addressed for the upcoming Rails 2&#46;0 release&#46;</p> <p>Finally, we noted that deployment could be a pain with so many Rails applications to keep running&#46; To that end, we are leveraging JRuby and Glassfish to make this a non&#45;issue, as we simply WAR up our Rails applications with <a href="http://blog.nicksieger.com/articles/2007/09/04/warbler-a-little-birdie-to-introduce-your-rails-app-to-java">warbler</a> and let Glassfish take care of the rest&#46; Performance is still an open question, but we plan to roll up our sleeves and make sure this combination really hums&#46;</p> <p>Enjoy the demos! Feel free to drop me an email if you have any questions or troubles with them&#46;</p> Sat, 06 Oct 2007 12:04:00 +0000 urn:uuid:d9edbea6-8e0e-43b6-af40-7d8bb3d69f52 Nick Sieger http://blog.nicksieger.com/articles/2007/10/06/railsconf-europe-hydra railsconf railsconfeurope2007 http://blog.nicksieger.com/articles/trackback/301 RailsConf Europe: David Heinemeier Hansson <h2>Rebel With a Cause</h2> <p>Rails is no longer the James Dean character, looking outward, trying to convince you of something&#46; It&#8217;s no longer about a rebellion or a revolution&#46; Instead, Rails is settling in as a passionate, inward&#45;looking craftsperson&#46;</p> <p>After the rebellion, settle in and enjoy the results of your work&#46; David hasn&#8217;t been working directly on Rails too much, instead he&#8217;s been enjoying it&#46;</p> <p>And it&#8217;s not about David anymore&#46; It&#8217;s about You (cue the Time Person of the Year cover)&#46; David wants Rails to be more friendly to newcomers&#46;</p> <p><a href="http://dev.rubyonrails.org/report/12">Report #12: Verified Patches</a>&#46; Encouraging the community to approve patches, rather than limiting the decisions to the core&#46; Opening up Rails&#46; (Also, unfortunately looking a little scarce at the moment&#46; <em>Update: turns out it&#8217;s empty because patches are quickly applied, not because there aren&#8217;t any submitted!</em>)</p> <p>David screened the original Rails movie &#45;&#45; showing Apache setup, manually creating databases and tables&#46; He quickly lost patience for it&#46;</p> <p>Compare to the current state of the art, with everything down to the routes and migrations gets created for you, lowering the barrier to entry (example: a new rake task <code>db:create:all</code>)&#46;</p> <p>Rails 2&#46;0 is largely about continual improvement and removing the cruft:</p> <ul> <li>Cookie&#45;based session store as the default</li> <li>Routing: <code>map.root</code></li> <li>Removing the dynamic <code>scaffold :posts</code> feature</li> <li><code>map.namespace</code> and <code>script/generate controller admin::posts</code></li> <li><code>*.html.erb</code> files with the MIME type and renderer baked into the filename, since the two are now mutually exclusive&#46;</li> <li>Automatically named partials with <code>render :partial =&gt; @posts</code> resolving to <code>_post.html.erb</code></li> <li>Namespacing and named routes:</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">mop</span><span class="punct">.</span><span class="ident">namespace</span> <span class="symbol">:admin</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">admin</span><span class="punct">|</span> <span class="ident">admin</span><span class="punct">.</span><span class="ident">resources</span> <span class="symbol">:posts</span> <span class="keyword">end</span> <span class="comment"># ...</span> <span class="ident">link_to</span> <span class="punct">'</span><span class="string">Show</span><span class="punct">',</span> <span class="punct">[</span><span class="symbol">:admin</span><span class="punct">,</span> <span class="ident">post</span><span class="punct">]</span></code></pre></div> <ul> <li>HTTP authentication</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Admin::PostsController</span> <span class="punct">&lt;</span> <span class="constant">ApplicationController</span> <span class="ident">before_filter</span> <span class="symbol">:ensure_administrator</span> <span class="comment"># ...</span> <span class="ident">private</span> <span class="keyword">def </span><span class="method">ensure_administrator</span> <span class="ident">authenticate_or_request_with_http_basic</span><span class="punct">(&quot;</span><span class="string">Blog Admin</span><span class="punct">&quot;)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">user</span><span class="punct">,</span><span class="ident">pass</span><span class="punct">|</span> <span class="ident">username</span> <span class="punct">==</span> <span class="punct">&quot;</span><span class="string">dhh</span><span class="punct">&quot;</span> <span class="punct">&amp;&amp;</span> <span class="ident">password</span> <span class="punct">==</span> <span class="punct">&quot;</span><span class="string">123</span><span class="punct">&quot;</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="keyword">end</span></code></pre></div> <ul> <li>Custom layouts for specific user agents (say, oh, the iPhone)&#46; Views can also be rendered, e&#46;g&#46;, <code>index.iphone.erb</code>&#46;</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">ApplicationController</span> <span class="punct">&lt;</span> <span class="constant">ActionController</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">before_filter</span> <span class="symbol">:adjust_format_for_iphone</span> <span class="keyword">def </span><span class="method">adjust_format_for_iphone</span> <span class="keyword">if</span> <span class="ident">request</span><span class="punct">.</span><span class="ident">env</span><span class="punct">[&quot;</span><span class="string">HTTP_USER_AGENT</span><span class="punct">&quot;][/</span><span class="regex">iPhone</span><span class="punct">/]</span> <span class="ident">request</span><span class="punct">.</span><span class="ident">format</span> <span class="punct">=</span> <span class="symbol">:iphone</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="comment"># initializer</span> <span class="constant">Mime</span><span class="punct">::</span><span class="constant">Type</span><span class="punct">.</span><span class="ident">register</span> <span class="punct">&quot;</span><span class="string">application/x-iphone</span><span class="punct">&quot;,</span> <span class="symbol">:iphone</span> <span class="comment"># In a controller method</span> <span class="ident">respond_to</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">format</span><span class="punct">|</span> <span class="ident">format</span><span class="punct">.</span><span class="ident">iphone</span> <span class="punct">{</span> <span class="ident">render</span> <span class="symbol">:text</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">Hello iPhone</span><span class="punct">&quot;,</span> <span class="symbol">:content</span> <span class="punct">=&gt;</span> <span class="constant">Mime</span><span class="punct">::</span><span class="constant">HTML</span> <span class="punct">}</span> <span class="keyword">end</span></code></pre></div> <ul> <li><code>atom_feed_helper</code>, a new plugin &#45;&#45; builder for Atom specified in <code>index.atom.builder</code></li> <li><code>&lt;%= yield :head %&gt;</code>, <code>content_for :head { auto_discovery_link(:atom, formatted_posts_url)}</code></li> <li>Debugger &#45;&#45; allows you to be lazy and leave your <code>breakpoint</code>s in your production code, not that you&#8217;d actually want to do that&#46; Dumps you into irb where you can inspect variables, etc&#46; but you can also drop down another level to see the call hierarchy, etc&#46;</li> </ul> <p>So when will we see Rails 2&#46;0? The preview release is coming, hopefully before conference end&#46;</p> Tue, 18 Sep 2007 08:14:00 +0000 urn:uuid:b1cf2100-7876-4946-9082-8b8054a24bd3 Nick Sieger http://blog.nicksieger.com/articles/2007/09/18/railsconf-europe-david-heinemeier-hansson railsconf railsconfeurope2007 http://blog.nicksieger.com/articles/trackback/290 RailsConf Europe: (Prag-) Dave Thomas <p><em>(Written from Dave&#8217;s perspective, in the first person, but paraphrased)</em></p> <p>What is a relevant topic in Germany? Engineering&#46; Except there&#8217;s no such thing as software engineering&#46; The software equivalent of building a bridge is taking a whole lot of dirt that fills in a hole&#46;</p> <p>So what makes engineering good? I look for elegance and beauty&#46;</p> <p>Fred Brooks &#45;&#45; Mythical Man&#45;Month&#46; Not a single thing in software engineering has changed in the 30 years since the book was written&#46; Go out and order it tonight if you haven&#8217;t read it&#46;</p> <p>We are privileged, because we get to start with nothing&#46; Anything we can conceive of, we can create&#46; And so, we suffer the same problems as poets suffer&#46;</p> <p>Writer&#8217;s block: a blank page standing in the way of getting started&#46; Painting: a blank canvas without structure or form&#46; Software project: a blank editor buffer&#46;</p> <p>Leonardo was commissioned to build a statue&#46; But, having never bronzed in his life, he picked up a scrap of paper and drew sketches&#46; He&#8217;s prototyping on paper, but in reality he&#8217;s prototyping in his mind, getting his brain thinking about what he&#8217;s doing&#46;</p> <p>We could do more of this experimentation&#46; Whiteboard, index cards, we eschew them for scaffolding or other crutches&#46; But we could think of more ideas if we got away from the familiar and tossed around new, fresh ideas&#46;</p> <p>The idea that we sit down and start coding the application is crazy&#46; We don&#8217;t know what it&#8217;s supposed to be&#46; Why should we fool ourselves into thinking that this works?</p> <p>Artists draw cartoons, often a fully rendered version of a painting&#46; If they don&#8217;t like the cartoon, it survives, but the final product probably takes a different form&#46;</p> <p>With Rails we can do rapid end&#45;to&#45;end prototyping&#46; Scaffolding helps with this, and it probably won&#8217;t make it into the end result&#46;</p> <p>So start anyway, and be prepared to throw it away&#46; Write tests, use them as tracer bullets&#46; And act on worry&#46; Listen to the inner voice that tells you when something is wrong&#46;</p> <p>Sistine Chapel: brilliant example of modularization&#46; It shows you how to conceive of doing a huge project without the fret of focusing on the entire thing&#46;</p> <p>Another example: comic books&#46; You&#8217;re splitting up the product into time slices&#46; Limit how much you do, and leave open the possibility of continuing at a later day&#46; Know when to stop&#46;</p> <p>Satisfy the customer&#46; Compare portraits to pictures&#46; The best portraits, while not always faithful to the real image of the subject, still achieve the goal of satisfying the customer&#46;</p> <p>There is art in engineering, and engineering in art&#46; Neither is an either/or proposition&#46; Art and engineering are mutually supportive, in that you can&#8217;t have one without another&#46;</p> <p>With Ruby and Rails, we have a responsibility to uphold&#46; Rails is a canvas, so be an artist&#46; Create something great&#46; But we also should create something beautiful&#46; Sign your name by your work, and take pride in it&#46;</p> Tue, 18 Sep 2007 08:08:34 +0000 urn:uuid:b558ff15-96dd-4ee7-9fca-813639290095 Nick Sieger http://blog.nicksieger.com/articles/2007/09/18/railsconf-europe-prag-dave-thomas railsconf railsconfeurope2007 http://blog.nicksieger.com/articles/trackback/289