<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>BuildingWebApps Articles</title>
  
  <link href="/feeds/articles" rel="alternate" />
  <id>http://buildingwebapps.com/articles</id>
  <updated>2009-04-08T17:00:00Z</updated>
  <author>
    <name>BuildingWebApps.com</name>
  </author>
  <link rel="self" href="http://feeds.feedburner.com/buildingwebappsarticles" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>Web 2.0 Expo: TV and Radio with an API</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/fya4hkLLf9k/17898-web-2-0-expo-tv-and-radio" rel="alternate" />
    <id>http://buildingwebapps.com/articles/17898-web-2-0-expo-tv-and-radio</id>
    <updated>2009-04-08T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>National Public Radio (NPR) is changing what it means to be a news organization. While traditional news organizations want to keep their content close, NPR has taken the approach of making content widely available via an API -- an approach they call "brand and release."</summary>
    <content type="html">
&lt;p&gt;National Public Radio (&lt;span class="caps"&gt;NPR&lt;/span&gt;) is changing what it means to be a news organization. While traditional news organizations want to keep their content close, &lt;span class="caps"&gt;NPR&lt;/span&gt; has taken the approach of making content widely available via an &lt;span class="caps"&gt;API&lt;/span&gt; &amp;ndash; an approach they call &amp;#8220;brand and release.&amp;#8221; They&amp;#8217;ve made 250,000 stories, going back 13 years, available through their &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Zack Brand from &lt;span class="caps"&gt;NPR&lt;/span&gt; said that the &lt;a href='http://npr.org/api'&gt;&lt;span class="caps"&gt;NPR&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; is getting about 2 million requests per month, and there are 1,300 registrants (you have to register to get access to the &lt;span class="caps"&gt;API&lt;/span&gt;). Content is available in a variety of formats; so far, 51% of requests use &lt;span class="caps"&gt;XML&lt;/span&gt;, 20% &lt;span class="caps"&gt;RSS&lt;/span&gt;, and 23% widgets.&lt;/p&gt;
&lt;p&gt;(Another notable new organization that has been making some content available via an &lt;span class="caps"&gt;API&lt;/span&gt; is the New York Times, which has an &lt;a href='http://open.blogs.nytimes.com/2009/02/04/announcing-the-article-search-api/'&gt;article search &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;, among others.)&lt;br /&gt;
	&lt;br /&gt;
&lt;p&gt;Also participating in this session was Robin Sloan from &lt;a href='http://current.tv'&gt;Current.tv&lt;/a&gt;. Current made interesting use of Twitter streams as part of its presidential debate coverage. The hash tag they created for people to tag their posts, #current, was the third most popular Twitter tag during the debates, bested only by the tags for the candidates themselves.&lt;/p&gt;
&lt;p&gt;Current built an application to provide a mash up of various data sources, including Digg, on election day. In true agile fashion, they made multiple software updates even after the show began broadcasting!&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=fya4hkLLf9k:v5B0hiNObiM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=fya4hkLLf9k:v5B0hiNObiM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=fya4hkLLf9k:v5B0hiNObiM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=fya4hkLLf9k:v5B0hiNObiM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/fya4hkLLf9k" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/17898-web-2-0-expo-tv-and-radio</feedburner:origLink></entry>
  <entry>
    <title>Web 2.0 Expo: Web Developer Tools</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/goq_SX3wGgY/17897-web-2-0-expo-web-developer-tools" rel="alternate" />
    <id>http://buildingwebapps.com/articles/17897-web-2-0-expo-web-developer-tools</id>
    <updated>2009-04-08T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Ben Galbraith and Dio Almaer of Ajaxian and the developer tools group at Mozilla gave a wide-ranging talk on web developer tools. </summary>
    <content type="html">
&lt;p&gt;Ben Galbraith and Dio Almaer of &lt;a href='http://ajaxian.com'&gt;Ajaxian&lt;/a&gt; and the &lt;a href='http://labs.mozilla.com/2008/10/developer-tools-and-the-open-web/'&gt;developer tools group at Mozilla&lt;/a&gt; gave a wide-ranging talk on web developer tools. They noted that the web often seems more like a hack than a platform &amp;mdash; it&amp;#8217;s amazing that developers are able to make web apps do the things they do. This is especially true with Ajax raising the bar for interactivity, and sites turning into applications instead of documents. They&amp;#8217;re out to make the web a better platform.&lt;/p&gt;
&lt;p&gt;Some future technologies that have them excited:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;HTML5 canvas&lt;/li&gt;
  &lt;li&gt;Fast JavaScript &amp;mdash; kicked off by Chrome, Firefox&amp;#8217;s TraceMonkey&lt;/li&gt;
  &lt;li&gt;Web workers, giving web apps the ability to have background threads&lt;/li&gt;
  &lt;li&gt;Desktop integration, such as &lt;a href='http://fluidapp.com/'&gt;Fluid&lt;/a&gt;, &lt;a href='http://labs.mozilla.com/projects/prism/'&gt;Prism&lt;/a&gt;, &lt;a href='http://www.adobe.com/products/air/'&gt;Adobe Air&lt;/a&gt;, and &lt;a href='http://titaniumapp.com/'&gt;Titanium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As part of its efforts to improve the web as a platform, Mozilla is working on an open web tools directory, as well as a variety of development projects.&lt;/p&gt;
&lt;p&gt;Ben and Dio noted that Firebug blew away existing tools and set a new standard for web development tools, providing a comprehensive set of tools in the browser itself. Other browsers have followed with IE8 and Safari 3.0 both providing good tools.&lt;/p&gt;
&lt;p&gt;Mozilla Labs has a relatively new project called &lt;a href='http://labs.mozilla.com/projects/bespin/'&gt;Bespin&lt;/a&gt;, a web-based code editor that is intended to be a showcase for &lt;span class="caps"&gt;HTML&lt;/span&gt; 5. This project is still young, and it won&amp;#8217;t run on an flavor of IE for a while, but it looks very promising.&lt;/p&gt;
&lt;p&gt;Mozilla Labs is also working on a grid-based layout system using JavaScript and HTML5 canvas; so far, there&amp;#8217;s not much on the web site about this project, but an announcement is due soon.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=goq_SX3wGgY:55KSGq3I-h0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=goq_SX3wGgY:55KSGq3I-h0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=goq_SX3wGgY:55KSGq3I-h0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=goq_SX3wGgY:55KSGq3I-h0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/goq_SX3wGgY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/17897-web-2-0-expo-web-developer-tools</feedburner:origLink></entry>
  <entry>
    <title>Web 2.0 Expo: Social Media</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/ITX8WxICKhQ/17896-web-2-0-expo-social-media" rel="alternate" />
    <id>http://buildingwebapps.com/articles/17896-web-2-0-expo-social-media</id>
    <updated>2009-04-08T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>The conference sessions at Web 2.0 Expo had a major emphasis on social media. I only attended a couple of these talks, about which I have brief comments below; at the end of the article, I have links to several others.</summary>
    <content type="html">
&lt;p&gt;The conference sessions at Web 2.0 Expo had a major emphasis on social media. I only attended a couple of these talks, about which I have brief comments below; at the end of the article, I have links to several others.&lt;/p&gt;
&lt;h2&gt;Social Media Marketing &amp;#8211; why it fails and how to fix it&lt;/h2&gt;
&lt;p&gt;This one felt somewhat remedial to me, with the essential points being:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Be authentic. You need to be a person, not just a representative of a company.&lt;/li&gt;
	&lt;li&gt;It&amp;#8217;s hard to change the marketing culture in an organization to deal well with social media. (A point that I was glad to gloss over, being in my tiny organization that doesn&amp;#8217;t have this sort of problem.)&lt;/li&gt;
	&lt;li&gt;It&amp;#8217;s a conversation. (If in doubt, go read The Cluetrain Manifesto.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;The Whuffie Factor&lt;/h2&gt;&lt;/p&gt;
&lt;p&gt;Taking a completely different approach to similar material, Tara Hunt gave what I found to be the most inspiring and engaging talk of the conference: The Whuffie Factor.&lt;/p&gt;
&lt;p&gt;Since both the slides and the video have been posted, I&amp;#8217;ll let her speak for herself.&lt;/p&gt;
&lt;h3&gt;Slides&lt;/h3&gt;
&lt;div style="width:425px;text-align:left" id="__ss_1242483"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/missrogue/whuffie-at-web-20-expo?type=powerpoint" title="Whuffie at Web 2.0 Expo"&gt;Whuffie at Web 2.0 Expo&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=whuffiepresentation-090402205538-phpapp01&amp;stripped_title=whuffie-at-web-20-expo" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=whuffiepresentation-090402205538-phpapp01&amp;stripped_title=whuffie-at-web-20-expo" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;p&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/missrogue"&gt;Tara Hunt&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Video&lt;/h3&gt;
&lt;p&gt;&lt;object width="480" height="360"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3983571&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=3983571&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="480" height="360"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/3983571"&gt;The Whuffie Factor: The 5 Keys for Maxing Social Capital and Winning with Online Communities (Tara Hunt)&lt;/a&gt; from &lt;a href="http://vimeo.com/steffan"&gt;Steffan Antonas&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Other Social Media Talks&lt;/h2&gt;&lt;/p&gt;
&lt;h3&gt;Designing Social Interfaces&lt;/h3&gt;
&lt;p&gt;&lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzkxNjMwNDk1MjkmcHQ9MTIzOTI1MDk2MTA5NiZwPTEwMTkxJmQ9Jmc9MiZ*PSZvPWJmNmQ*NjE2YzQ*NDQ4YTdiNDk3ZjU*MDkzZmM1NDk*.gif" /&gt;&lt;div style="width:425px;text-align:left" id="__ss_1229890"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/emalone/social-patterns-talk-web-20-version?type=powerpoint" title="Social Patterns Talk - Web 2.0 version"&gt;Social Patterns Talk &amp;#8211; Web 2.0 version&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=socialpatternstalk-web2-090331165811-phpapp02&amp;stripped_title=social-patterns-talk-web-20-version" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=socialpatternstalk-web2-090331165811-phpapp02&amp;stripped_title=social-patterns-talk-web-20-version" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/emalone"&gt;Erin Malone&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Designing Social Websites&lt;/h3&gt;
&lt;div style="width:425px;text-align:left" id="__ss_1236224"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/cwodtke/designing-the-social-web-for-web20-expo?type=powerpoint" title="Designing the Social Web (for Web2.0 expo)"&gt;Designing the Social Web (for Web2.0 expo)&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=designingsocialweb20low-090401174528-phpapp02&amp;stripped_title=designing-the-social-web-for-web20-expo" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=designingsocialweb20low-090401174528-phpapp02&amp;stripped_title=designing-the-social-web-for-web20-expo" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;p&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/cwodtke"&gt;cwodtke&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Building Sites Around Social Objects&lt;/h3&gt;
&lt;p&gt;&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=4071624&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=4071624&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/4071624"&gt;Building Sites Around Social Objects (Web 2.0 Expo &amp;#8211; Jyri Engestrom, Google)&lt;/a&gt; from &lt;a href="http://vimeo.com/steffan"&gt;Steffan Antonas&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Social Media Buyer&amp;#8217;s Guide&lt;/h3&gt;
&lt;p&gt;&lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzkyNTEwOTgxMjImcHQ9MTIzOTI1MTE4MTEzMyZwPTEwMTkxJmQ9Jmc9MiZ*PSZvPWJmNmQ*NjE2YzQ*NDQ4YTdiNDk3ZjU*MDkzZmM1NDk*.gif" /&gt;&lt;div style="width:425px;text-align:left" id="__ss_1245456"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/socialmedia/social-media-buyers-guide-preview?type=powerpoint" title="Social Media Buyers Guide Preview"&gt;Social Media Buyers Guide Preview&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=smbgfinw2e-090403122628-phpapp01&amp;stripped_title=social-media-buyers-guide-preview" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=smbgfinw2e-090403122628-phpapp01&amp;stripped_title=social-media-buyers-guide-preview" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/socialmedia"&gt;socialmedia&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Beyond Buzz: Measuring a Conversation&lt;/h3&gt;
&lt;p&gt;&lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzkzODkzMDQ*MjMmcHQ9MTIzOTM4OTM4MjMyNCZwPTEwMTkxJmQ9Jmc9MiZ*PSZvPTBkZDRjNzZmYWEyNDQzOTFhODEyZTE3MzE2NWNkZDhj.gif" /&gt;&lt;div style="width:425px;text-align:left" id="__ss_1242672"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/kategn/beyond-buzz-web-20-expo-kniederhoffer-msmith-1242672?type=powerpoint" title="Beyond Buzz - Web 2.0 Expo - K.Niederhoffer &amp;amp; M.Smith"&gt;Beyond Buzz &amp;#8211; Web 2.0 Expo &amp;#8211; K.Niederhoffer &amp;amp; M.Smith&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=web2-kn-ms-final-3-30-090402221335-phpapp02&amp;stripped_title=beyond-buzz-web-20-expo-kniederhoffer-msmith-1242672" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=web2-kn-ms-final-3-30-090402221335-phpapp02&amp;stripped_title=beyond-buzz-web-20-expo-kniederhoffer-msmith-1242672" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/kategn"&gt;kategn&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=ITX8WxICKhQ:VOG4uqA8uS4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=ITX8WxICKhQ:VOG4uqA8uS4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=ITX8WxICKhQ:VOG4uqA8uS4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=ITX8WxICKhQ:VOG4uqA8uS4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/ITX8WxICKhQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/17896-web-2-0-expo-social-media</feedburner:origLink></entry>
  <entry>
    <title>Web 2.0 Expo San Francisco Spring 2009</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/g_hJbYvkFhc/17831-web-2-0-expo-san-francisco-spring" rel="alternate" />
    <id>http://buildingwebapps.com/articles/17831-web-2-0-expo-san-francisco-spring</id>
    <updated>2009-04-05T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Last week's Web 2.0 Expo seemed like a successful event, with a good-sized crowd despite the economic malaise &amp;ndash; due in part, no doubt, to unusually aggressive discounting and promotion. With multiple tracks across four days (one day of workshops and three of conference sessions) there was much more to see than any one person could possibly attend.</summary>
    <content type="html">
&lt;h2&gt;March 31 &amp;#8211; April 3, San Francisco&lt;/h2&gt;
&lt;p&gt;Last week&amp;#8217;s Web 2.0 Expo seemed like a successful event, with a good-sized crowd despite the economic malaise – due in part, no doubt, to unusually aggressive discounting and promotion. With multiple tracks across four days (one day of workshops and three of conference sessions) there was much more to see than any one person could possibly attend.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a few articles that we&amp;#8217;ve written about talks at the conference:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href='http://www.buildingwebapps.com/articles/17896-web-2-0-expo-social-media'&gt;Web 2.0 Expo: Social Media&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://www.buildingwebapps.com/articles/17897-web-2-0-expo-web-developer-tools'&gt;Web 2.0 Expo: Web Developer Tools&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://www.buildingwebapps.com/articles/17898-web-2-0-expo-tv-and-radio'&gt;TV and Radio with an &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many of the presentations are available online, as slides and/or videos:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href='http://www.web2expo.com/webexsf2009/public/schedule/proceedings'&gt;Official download site for Web 2.0 Presentations&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://www.slideshare.net/tag/w2e'&gt;Presentation slides on SlideShare&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://vimeo.com/videos/search:w2e'&gt;Videos on Vimeo&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://www.youtube.com/results?search_type=&amp;search_query=web+2.0+expo+sf+2009&amp;aq=f'&gt;Videos on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And to go beyond the presentations and get more flavor of the event:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href='http://search.twitter.com/search?q=%23w2e'&gt;Twitter Stream&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href='http://www.flickr.com/search/?q=w2e'&gt;Photos on Twitter&lt;/a&gt;&lt;/li&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=g_hJbYvkFhc:MY47DU5WKjU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=g_hJbYvkFhc:MY47DU5WKjU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=g_hJbYvkFhc:MY47DU5WKjU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=g_hJbYvkFhc:MY47DU5WKjU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/g_hJbYvkFhc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/17831-web-2-0-expo-san-francisco-spring</feedburner:origLink></entry>
  <entry>
    <title>Enhancing Conditional Routing in Rails</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/hnzPodFAfQU/7082-enhancing-conditional-routing-in-rails" rel="alternate" />
    <id>http://buildingwebapps.com/articles/7082-enhancing-conditional-routing-in-rails</id>
    <updated>2008-08-26T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>Rails' routing infrastructure supports the concept of conditional routes: preconditions that must be satisfied before a particular route will trigger. Rails 2.1 supports one built-in condition, HTTP method checking, which is of some use but rather limited. What I needed was to be able to limit certain routes to only trigger when a particular host-name was used to access the application. I show one implementation in this article.</summary>
    <content type="html">
&lt;p&gt;Rails&amp;#8217; routing infrastructure supports the concept of conditional routes: preconditions that must be satisfied before a particular route will trigger. Rails 2.1 supports one built-in condition, &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; method checking, which is of some use but rather limited. What I needed was to be able to limit certain routes to only trigger when a particular host-name was used to access the application.&lt;/p&gt;
&lt;p&gt;I thought I&amp;#8217;d have to write messy additional logic until a little comment tucked away in ActionController::Routing::RouteSet and ActionController::Routing::Routing caught my eye. Here I briefly show you how to leverage this functionality for your own purposes.&lt;/p&gt;
&lt;h2&gt;The Goal &amp;#8212; Conditional Routes in routes.rb&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s work backwards and see the result I was aiming for. I wanted to expand the existing capabilities of the routing engine and be able to restrict routes to specific hosts. The conditional routing option works by adding a parameter to your route specifications. Here are some examples:&lt;/p&gt;
&lt;pre&gt;
map.with_options(:controller =&amp;amp;gt; 'feeds', :conditions =&amp;amp;gt; {:hosts =&amp;amp;gt; MY_HOSTS}) do |feed|
  feed.feeds_articles '/feeds/articles', :action =&amp;amp;gt; 'articles'
  feed.feeds_podcast '/feeds/podcast', :action =&amp;amp;gt; 'podcast'
end
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;
map.resources :podcasts, :conditions =&amp;amp;gt; {:hosts =&amp;amp;gt; MY_HOSTS}, 
   :member =&amp;amp;gt; {:show_notes =&amp;amp;gt; :get, :transcript =&amp;amp;gt; :get},
   :collection =&amp;amp;gt; {:admin =&amp;amp;gt; :get} do |podcast|
     podcast.resources :comments, :member =&amp;amp;gt; {:report_as_ham =&amp;amp;gt; :get, :report_as_spam =&amp;amp;gt; :get}
   end
&lt;/pre&gt;
&lt;p&gt;or even&lt;/p&gt;
&lt;pre&gt;
map.connect ':controller/:action/:id', :conditions =&amp;amp;gt; {:hosts =&amp;amp;gt; MY_HOSTS}
&lt;/pre&gt;
&lt;p&gt;In Rails 2.1, however, no such option &lt;code&gt;:hosts&lt;/code&gt; exists, only an option to check the &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; method via &lt;code&gt;:method&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;The Implementation&lt;/h2&gt;
&lt;p&gt;I haven&amp;#8217;t really ever needed to use the conditional routing support before, and didn&amp;#8217;t really think about it due to it only supporting the &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; method check. For that reason, I originally thought I&amp;#8217;d have to write my own logic, either patching existing Routing routines (nearly right!) or by writing new stuff that could get messy (bad idea).&lt;/p&gt;
&lt;p&gt;During a last scan through the code for the keyword &amp;#8220;conditions&amp;#8221;, I saw this comment:&lt;/p&gt;
&lt;pre&gt;
# Plugins may override this method to add other conditions, like checks on
# host, subdomain, and so forth. Note that changes here only affect route
# recognition, not generation.
&lt;/pre&gt;
&lt;p&gt;Good, a place to start afterall! The solution is elegant as it only requires overriding two simple routines. You can do this in your own app by writing code that gets loaded at startup. Here is one implementation in its entirety:&lt;/p&gt;
&lt;pre&gt;
require 'action_controller'

module ActionController
  module Routing
    class RouteSet
      def extract_request_environment(request)
        { :method =&amp;amp;gt; request.method, :host =&amp;amp;gt; request.host }
      end
    end

    class Route
      def recognition_conditions
        result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"]
        result &amp;amp;lt;&amp;amp;lt; "conditions[:method] === env[:method]" if conditions[:method]
        result &amp;amp;lt;&amp;amp;lt; "conditions[:hosts].include?(env[:host])" if conditions[:hosts]
        result
      end
    end
  end
end	
&lt;/pre&gt;
&lt;p&gt;My code is very simplistic and tuned for my needs, but gives you an example of where to patch in. Here, I simply supply a list of host names I care about, and check the incoming host against that list.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;extract_request_environment&lt;/code&gt; to parse out and store any data you will want to use in your conditional checks. This data will be available in the &lt;code&gt;env&lt;/code&gt; hash later on.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;recognition_conditions&lt;/code&gt; generates an Array of String objects that contain the Ruby code that will be used to build dynamic conditional test methods when the routing engine compiles the routes data in &lt;code&gt;routes.rb&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I drop the source file into my project&amp;#8217;s pre-existing &lt;code&gt;lib/plugins/action_controller_extensions/lib&lt;/code&gt; directory as &lt;code&gt;action_controller_extensions.rb&lt;/code&gt; and include an &lt;code&gt;init.rb&lt;/code&gt; loader stub in my &lt;code&gt;lib/plugins/action_controller_extensions&lt;/code&gt; directory:&lt;/p&gt;
&lt;pre&gt;
require 'action_controller_extensions'	
&lt;/pre&gt;
&lt;p&gt;My app deals with loading up such &amp;#8220;plugins&amp;#8221; at startup. You may have a different set-up. You can get the same effect by putting a &lt;code&gt;require&lt;/code&gt; for the main source file in your startup code.&lt;/p&gt;
&lt;p&gt;It would be great to see other generally useful conditionals contributed by the community.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=hnzPodFAfQU:Qu7vMnjrNYE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=hnzPodFAfQU:Qu7vMnjrNYE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=hnzPodFAfQU:Qu7vMnjrNYE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=hnzPodFAfQU:Qu7vMnjrNYE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/hnzPodFAfQU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/7082-enhancing-conditional-routing-in-rails</feedburner:origLink></entry>
  <entry>
    <title>Startup Camp and Foo Camp</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/0elKjtV8mf8/6513-startup-camp-and-foo-camp" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6513-startup-camp-and-foo-camp</id>
    <updated>2008-07-20T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>I feel lucky to have been able to attend last week's Startup Camp and Foo Camp. These are unusual, invitation-only events, with extraordinary collections of people. Getting an invitation requires some mix of accomplishment, connections, and luck.</summary>
    <content type="html">
&lt;p&gt;I feel lucky to have been able to attend last week&amp;#8217;s Startup Camp and Foo Camp. These are unusual, invitation-only events, with extraordinary collections of people. Getting an invitation requires some mix of accomplishment, connections, and luck.&lt;/p&gt;
&lt;p&gt;They are exclusive events not for the sake of exclusivity, but because they only work at a limited size. &lt;a href="http://oreilly.com/about/"&gt;O&amp;#8217;Reilly Media&lt;/a&gt;, which hosts the events and foots the bill (there&amp;#8217;s no registration fee), gets to pick the attendees from its diverse range of colleagues and contacts.&lt;/p&gt;
&lt;h2&gt;Startup Camp&lt;/h2&gt;
&lt;p&gt;This was the first-ever Startup Camp, created by O&amp;#8217;Reilly&amp;#8217;s venture fund, &lt;a href="http://oatv.com"&gt;O&amp;#8217;Reilly Alpha Tech Ventures&lt;/a&gt;. &lt;span class="caps"&gt;&lt;span class="caps"&gt;OATV&lt;/span&gt;&lt;/span&gt; set up a two-day program, with a variety of startup veterans to give talks and lead discussions, and invited startups to apply. We were fortunate to be one of the &lt;a href="http://www.oatv.com/foo"&gt;7 startups accepted&lt;/a&gt; &amp;#8212; doubly so because getting into Startup Camp provided a much-sought-after invitation to Foo Camp as well.&lt;/p&gt;
&lt;p&gt;The companies invited to Startup Camp spanned an incredibly broad range, from  custom jewelry for tweens  (&lt;a href="http://whirlybelle.com"&gt;WhirlyBelle&lt;/a&gt; from Replicator) to open-source server management software (Puppet from &lt;a href="http://reductivelabs.com"&gt;Reductive Labs&lt;/a&gt;) and open-source synthetic biology (&lt;a href="http://ginkgobioworks.com/"&gt;Ginkgo BioWorks&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The presenters included Tim O&amp;#8217;Reilly and Dale Dougherty (O&amp;#8217;Reilly), Bryce Roberts (&lt;span class="caps"&gt;&lt;span class="caps"&gt;OATV&lt;/span&gt;&lt;/span&gt;), Esther Dyson, Evan Williams (Blogger, Twitter), Marc Hedlund (Wesabe), Michael Arrington (TechCrunch), Mark Fletcher (Bloglines), Dave McClure (500 Hats), Howard Morgan (First Round Capital), and Kathy Sierra (Creating Passionate Users).&lt;/p&gt;
&lt;div style='width:650px; float:left:padding-right:10px'&gt;
&lt;p&gt;&lt;img src="/foo_camp_08-1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Since this was an off-the-record session, you won&amp;#8217;t see much reporting of the content, and I can&amp;#8217;t add much to that either. Keep it in mind next summer if you find yourself leading a new startup and want to apply.&lt;/p&gt;
&lt;p&gt;Dave McClure&amp;#8217;s &lt;a href="http://www.slideshare.net/dmc500hats/startup-metrics-for-pirates-foo-camp-2008"&gt;Startup Metrics for Pirates&lt;/a&gt; presentation is one talk whose slides have been made public. And the &amp;#8220;Entrepreneurial Proverbs&amp;#8221; session was inspired by older blog posts by the two presenters, &lt;a href="http://evhead.com/2005/11/ten-rules-for-web-startups.asp"&gt;Evan Williams&lt;/a&gt; and &lt;a href="http://radar.oreilly.com/2006/03/entrepreneurial-proverbs.html"&gt;Marc Hedlund&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Foo Camp&lt;/h2&gt;
&lt;p&gt;As exciting as Startup Camp was, it was a prelude to the much larger Foo Camp.&lt;/p&gt;
&lt;p&gt;Foo Camp was created by Tim O&amp;#8217;Reilly and his colleague Sara Winge in 2003, and John Battelle wrote one of the &lt;a href="http://www.cnn.com/2004/TECH/ptech/01/09/bus2.feat.geek.camp/"&gt;first articles&lt;/a&gt; about it. The name nominally stands for Friends Of O&amp;#8217;Reilly, and it is also a play on the use of &amp;#8220;foo&amp;#8221; as a stand-in variable name in programming examples (a practice that, incidentally, dates back to the 1960&amp;#8217;s). Tim wrote about &lt;a href="http://radar.oreilly.com/2007/06/foo-camp-takeaways.html"&gt;why Foo Camp&lt;/a&gt; last year.&lt;/p&gt;
&lt;p&gt;The business rationale for Foo Camp is that it gives the O&amp;#8217;Reilly team the opportunity to talk with hundreds of leading-edge thinkers, as they look for ideas for books and conferences.&lt;/p&gt;
&lt;div style='width:650px; float:left:padding-right:10px'&gt;
&lt;p&gt;&lt;img src="/foo_camp_08-5.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s actually camping at Foo Camp: while many attendees stay at local hotels, a lot of them camp on the back lawn, and inside the office buildings, at O&amp;#8217;Reilly. (For me, it&amp;#8217;s only a five-minute drive, since O&amp;#8217;Reilly is in my home town of Sebastopol, CA.)&lt;/p&gt;
&lt;p&gt;O&amp;#8217;Reilly aims to have about 250 people at Foo Camp, which requires turning away a lot of past attendees so they can invite lots of new people each year.&lt;/p&gt;
&lt;p&gt;Among the well-known entrepreneurs and technologists attending this year were Jimmy Wales, Joshua Schacter, Steven Souders, Adrian Holovaty, Tom Coates, Scott Berkun, Ze Frank, Dries Buytaert, and Caterina Fake. That&amp;#8217;s just a random selection of the better known names. There were dozens of other well-known folks, and dozens more inspired, creative folks who have lower profiles.&lt;/p&gt;
&lt;p&gt;Most of O&amp;#8217;Reilly&amp;#8217;s editors and conference directors were there, as well as many of its authors. &lt;a href="http://oatventures.com/investments/"&gt;&lt;span class="caps"&gt;OATV&lt;/span&gt;&amp;#8217;s portfolio companies&lt;/a&gt; were also well represented.&lt;/p&gt;
&lt;div style='width:650px; float:left:padding-right:10px'&gt;
&lt;p&gt;&lt;img src="/foo_camp_08-2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Foo Camp popularized the &amp;#8220;unconference&amp;#8221; format, in which the attendees create the program. The sponsors provide a chart with a grid of rooms and meeting times, and the attendees fill it in as they desire.&lt;/p&gt;
&lt;p&gt;The unconference format is best known from the proliferation of &lt;a href="http://barcamp.org/"&gt;Bar Camps&lt;/a&gt;, which were inspired by the early Foo Camps. (More geek humor here, as in foobar.)&lt;/p&gt;
&lt;p&gt;When this format was new, people were often hesitant to propose sessions, but no longer. The schedule board was 80% full within minutes. There&amp;#8217;s so many parallel tracks, and so many fascinating people, that you can only see a fraction of what goes on and meet a scattering of people.&lt;/p&gt;
&lt;div style='width:650px; float:left:padding-right:10px'&gt;
&lt;p&gt;&lt;img src="/foo_camp_08-3.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;One of my favorite sessions was on &lt;strong&gt;The Future of News&lt;/strong&gt;. Both news, as journalism, and newspapers, as businesses, are in a period of dramatic change and stress. Presenters included &lt;a href="http://blog.seattlepi.nwsource.com/netnative/bio.asp#bio100435"&gt;Monica Guzman&lt;/a&gt; of the Seattle Post-Intelligencer, &lt;a href="http://topics.nytimes.com/top/reference/timestopics/people/m/john_markoff/index.html"&gt;John Markoff&lt;/a&gt; and&lt;br /&gt;
&lt;a href="http://nickbilton.com/"&gt;Nick Bilton&lt;/a&gt; from the New York Times, &lt;a href="http://www.stevenlevy.com/"&gt;Steven Levy&lt;/a&gt; from NewsWeek, and&lt;br /&gt;
&lt;a href="http://public.resource.org"&gt;Carl Malamud&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other interesting sessions I joined covered topics including ubiquitous computing, curation vs. crowd-sourcing, pragmatic thinking and learning (Andy Hunt), personal genomics (Esther Dyson, 23andMe), and aggregation vs. copyright.&lt;/p&gt;
&lt;div style='width:650px; float:left:padding-right:10px'&gt;
&lt;p&gt;&lt;img src="/foo_camp_08-6.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Tim O&amp;#8217;Reilly debated Michael Arrington on whether it is important for Microsoft to develop its own search technology, or if getting it from Yahoo is a reasonable strategy. Danny Sullivan moderated. And yes, that is an inflatable elephant.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the pair of blog posts that inspired this session:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://radar.oreilly.com/2008/05/why-search-competition-isnt-the-point.html"&gt;Why Search Isn&amp;#8217;t the Point&lt;/a&gt;, by Tim O&amp;#8217;Reilly&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.techcrunch.com/2008/05/25/the-importance-of-a-competitive-search-market/"&gt;The Importance of a Competitive Search Market&lt;/a&gt;, by Michael Arrington&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Retrospection&lt;/h2&gt;
&lt;p&gt;I have no doubt that this event serves O&amp;#8217;Reilly well, but it nevertheless is a great contribution to the community. Rarely is such a diverse collection of extraordinary people brought together under such casual, low-pressure surroundings.&lt;/p&gt;
&lt;p&gt;Looking back on Foo Camp, there are so many people I wish I had been able to spend time with, and sessions I wish I had attended. I&amp;#8217;ll just have to hope for another invitation in years to come.&lt;/p&gt;
&lt;p&gt;As someone who spent a decade running conferences, I at first found the unconference format unsettling. The completely self-organizing nature of the event means that its quality is determined entirely by the attendees. But with a crowd like this one, that&amp;#8217;s a good thing.&lt;/p&gt;
&lt;h2&gt;More Foo Stuff&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://laughingsquid.com/foo-camp-2008-photos/"&gt;Laughing Squid&amp;#8217;s Pictures&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.flickr.com/photos/joi/sets/72157606108716088/"&gt;Joi Ito&amp;#8217;s Pictures&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.techcrunch.com/2008/07/14/foo-camp-2008-shangri-la-for-geeks/"&gt;Michael Arrington&amp;#8217;s article&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://perspectives.mvdirona.com/2008/07/14/FooCamp2008.aspx"&gt;James Hamilton&amp;#8217;s article&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.scottberkun.com/blog/2008/what-i-learned-at-foo-camp-08/"&gt;Scott Berkun&amp;#8217;s article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=0elKjtV8mf8:zdy8vtUUFxU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=0elKjtV8mf8:zdy8vtUUFxU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=0elKjtV8mf8:zdy8vtUUFxU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=0elKjtV8mf8:zdy8vtUUFxU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/0elKjtV8mf8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6513-startup-camp-and-foo-camp</feedburner:origLink></entry>
  <entry>
    <title>Setting up Rails on Tiger (Mac OS X 10.4)</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/G3wnIIWTXxI/6455-setting-up-rails-on-tiger-mac" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6455-setting-up-rails-on-tiger-mac</id>
    <updated>2008-07-19T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>This guide walks you through setup instructions for preparing a Mac OS X 10.4 (aka Tiger) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.</summary>
    <content type="html">
&lt;p&gt;This guide walks you through setup instructions for preparing a Mac OS X 10.4 (aka Tiger) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our &lt;a href="/course"&gt;LearningRails online course&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will end up with a development machine with the following baseline components:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Ruby and all basic Ruby utilities&lt;/li&gt;
	&lt;li&gt;Ruby Gems package manager&lt;/li&gt;
	&lt;li&gt;Subversion client&lt;/li&gt;
	&lt;li&gt;Git client&lt;/li&gt;
	&lt;li&gt;Native development tools (Xcode, C compiler)&lt;/li&gt;
	&lt;li&gt;MacPorts native code package manager&lt;/li&gt;
	&lt;li&gt;MySQL database client utilities and server&lt;/li&gt;
	&lt;li&gt;Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL&lt;/li&gt;
	&lt;li&gt;Programmer&amp;#8217;s editor or &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: In the command sequences we illustrate here, command line prompts are shown as a dollar sign (&lt;code&gt;$&lt;/code&gt;).&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;This guide assumes you have a Macintosh computer running the current Tiger operating system with up-to-date System Update patches applied. It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.&lt;/p&gt;
&lt;p&gt;You will need to have access to an Internet connection to complete various download steps.&lt;/p&gt;
&lt;p&gt;You will need to have administrator access to your computer to complete this guide. We will be using the &lt;code&gt;sudo&lt;/code&gt; command to run various command line programs and some of the Mac OS X native installers will also ask you for your password.&lt;/p&gt;
&lt;p&gt;It is helpful if you have access to your operating system installation discs.&lt;/p&gt;
&lt;h2&gt;The Recipe&lt;/h2&gt;
&lt;p&gt;Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.&lt;/p&gt;
&lt;p&gt;If you are planning on upgrading to Mac OS X 10.5 (Leopard), you should do so now and save some time setting up the Ruby environment. &lt;a href="http://www.buildingwebapps.com/articles/17-setting-up-rails-on-leopard-mac"&gt;Leopard comes with a current version of Ruby and it makes setting things up much easier&lt;/a&gt;. If you follow this guide and then upgrade to Leopard later, it is pretty simple to deactivate (or remove) the redundant components that are no longer needed.&lt;/p&gt;
&lt;h3&gt;Native Development Tools (X11 and Xcode 2.5)&lt;/h3&gt;
&lt;p&gt;MacPorts will use native development tools when installing many of the utilities listed in this guide. You will also need a native compiler to build many of the gems&amp;#8217; native libraries you are going to use. Apple provides a free native compiler tool set called Xcode. If you have your Tiger installation &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;, load it now. If you don&amp;#8217;t have an installation &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;, you can download the &lt;a href="http://developer.apple.com/tools/download/"&gt;Xcode 2.5 tools at Apple&amp;#8217;s Developer Web Site&lt;/a&gt;. (Note: Apple developer accounts are free.)&lt;/p&gt;
&lt;p&gt;Open the &lt;code&gt;Xcode Tools&lt;/code&gt; folder (or &lt;span class="caps"&gt;&lt;span class="caps"&gt;DMG&lt;/span&gt;&lt;/span&gt; file if you downloaded the package). Double click on the &lt;code&gt;XcodeTools.mpkg&lt;/code&gt; installer and select a standard install. This will take a few minutes to run:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installmac104_xcode.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;As an optional step, some tools require that the X11 window manager application be installed. Under Tiger, this is an optional install. You can find X11 on your Tiger installation &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt; or &lt;a href="http://www.apple.com/downloads/macosx/apple/macosx_updates/x11update2006113.html"&gt;download it from Apple&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;MacPorts&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; is a native code package manager for Macintosh software. This guide uses MacPorts to setup the Ruby tools, MySQL, and the Git distributed version control system. There are many other tools available in the MacPorts library, so it is well worth checking out.&lt;/p&gt;
&lt;p&gt;Download the &lt;a href="http://svn.macports.org/repository/macports/downloads/MacPorts-1.6.0/MacPorts-1.6.0-10.4-Tiger.dmg"&gt;Tiger Universal version&lt;/a&gt; (1.6.0 at the time of this writing) and double click the MacPorts &lt;span class="caps"&gt;&lt;span class="caps"&gt;DMG&lt;/span&gt;&lt;/span&gt; file to open it up. Double click on &amp;#8220;MacPorts-1.6.0.pkg&amp;#8221; to start the installer and select the default options.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installmac104_ports.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;After MacPorts completes installation, you need to adjust your command line &lt;code&gt;PATH&lt;/code&gt; environment variable so you can run the &lt;code&gt;port&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Fire up the Terminal program and enter the command:&lt;/p&gt;
&lt;pre&gt;
	$ open .bash_profile
&lt;/pre&gt;
&lt;p&gt;Note that there is a period in front of &amp;#8220;bash_profile&amp;#8221;. The bash shell configuration file should open in the TextEdit program.  If you don&amp;#8217;t have a .bash_profile, you can create a new one in your text editor and save it in your home directory.&lt;/p&gt;
&lt;p&gt;(By the way, we recommend &lt;a href="http://iterm.sourceforge.net/"&gt;iTerm&lt;/a&gt; as a nice open source replacement to the Apple Terminal program.)&lt;/p&gt;
&lt;p&gt;Inside of .bash_profile, find the line that starts with &lt;code&gt;export PATH=&lt;/code&gt;, if present. You are going to insert the new directories used by MacPorts into your path:&lt;/p&gt;
&lt;pre&gt;
	export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
&lt;/pre&gt;
&lt;p&gt;If you don&amp;#8217;t have a line that exports your &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt;, use the text exactly as above. If you do already have such a line, add the &lt;code&gt;/opt/local/bin:/opt/local/sbin:&lt;/code&gt; (note colons) after the first quote, but before any other paths. Here is an example:&lt;/p&gt;
&lt;pre&gt;
	export PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:$PATH"
&lt;/pre&gt;
&lt;p&gt;Save the file and close TextEdit. Open a new terminal window and have MacPorts update itself with the command:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port selfupdate
&lt;/pre&gt;
&lt;h3&gt;Ruby and Ruby Utilities (irb, ri, rdoc)&lt;/h3&gt;
&lt;p&gt;Tiger comes pre-installed with a version of Ruby that is out of date for day to day use. You will use MacPorts to upgrade to the latest production version of the Ruby toolset. In a terminal window type:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port install ruby
	Password:
	---&amp;amp;gt;  Fetching ncursesw
	---&amp;amp;gt;  Attempting to fetch ncurses-5.6.tar.gz from http://ftp.gnu.org/gnu/ncurses
	---&amp;amp;gt;  Verifying checksum(s) for ncursesw
	---&amp;amp;gt;  Extracting ncursesw
	---&amp;amp;gt;  Applying patches to ncursesw
	---&amp;amp;gt;  Configuring ncursesw
	---&amp;amp;gt;  Building ncursesw with target all
	---&amp;amp;gt;  Staging ncursesw into destroot
...
	---&amp;amp;gt;  Installing ncurses 5.6_0+darwin_8
	---&amp;amp;gt;  Activating ncurses 5.6_0+darwin_8
	---&amp;amp;gt;  Cleaning ncurses
	---&amp;amp;gt;  Fetching openssl
	---&amp;amp;gt;  Attempting to fetch openssl-0.9.8e.tar.gz from http://www.openssl.org/source/
...
	---&amp;amp;gt;  Fetching ruby
	---&amp;amp;gt;  Attempting to fetch ruby-1.8.6.tar.gz from http://www.ibiblio.org/pub/languages/ruby/1.8
	---&amp;amp;gt;  Attempting to fetch ruby-1.8.6.tar.gz from http://mirrors.sunsite.dk/ruby/1.8
	---&amp;amp;gt;  Verifying checksum(s) for ruby
	---&amp;amp;gt;  Extracting ruby
	---&amp;amp;gt;  Applying patches to ruby
	---&amp;amp;gt;  Configuring ruby
	---&amp;amp;gt;  Building ruby with target all
	---&amp;amp;gt;  Staging ruby into destroot
	---&amp;amp;gt;  Packaging tgz archive for ruby 1.8.6_0+thread_hooks
	---&amp;amp;gt;  Installing ruby 1.8.6_0+thread_hooks
	---&amp;amp;gt;  Activating ruby 1.8.6_0+thread_hooks
	---&amp;amp;gt;  Cleaning ruby
&lt;/pre&gt;
&lt;p&gt;Your output may be slightly different depending on the versions of software at the time you run these commands. The listing here was edited for brevity.&lt;/p&gt;
&lt;p&gt;You can check that Ruby is installed with:&lt;/p&gt;
&lt;pre&gt;
	$ which ruby
	/opt/local/bin/ruby
	$ ruby -v
	ruby 1.8.6 (2007-03-13 patchlevel 0) [powerpc-darwin8.11]
&lt;/pre&gt;
&lt;p&gt;You should seem similar responses. The important one is the first one which reports back the path of the program. If you are using the MacPorts Ruby, it will be located in &lt;code&gt;/opt/local/bin/&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Ruby Gems Package Manager&lt;/h3&gt;
&lt;p&gt;You next need to install the latest version of &lt;code&gt;gem&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;
	$ sudo port install rb-rubygems rb-termios
&lt;/pre&gt;
&lt;p&gt;Check the version that gets installed:&lt;/p&gt;
&lt;pre&gt;
	$ gem -v
	0.9.4
&lt;/pre&gt;
&lt;p&gt;You need 1.0.1 or newer. If you have an older version, you can update with the command line: &lt;code&gt;sudo gem update --system&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Installing a Subversion client&lt;/h3&gt;
&lt;p&gt;Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion client and you can use MacPorts to install it:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port install subversion +tools
&lt;/pre&gt;
&lt;h3&gt;Installing Git via MacPorts&lt;/h3&gt;
&lt;p&gt;Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. Currently Leopard doesn&amp;#8217;t install git by default, so we&amp;#8217;ll use MacPorts to quickly install git:&lt;/p&gt;
&lt;pre&gt;
 	$ sudo port install git-core +doc +svn
&lt;/pre&gt;
&lt;p&gt;This command installs the core git tools, the man page documentation, and integration with Subversion. This last is useful if you plan on migrating from or need to work with a legacy Subversion repository. The installation will take a while; it has a lot to load.&lt;/p&gt;
&lt;p&gt;Besides your own project version control, you&amp;#8217;ll typically use git when loading Rails 2.1 and various 3rd party plugins.&lt;/p&gt;
&lt;h3&gt;Installing MySQL via MacPorts&lt;/h3&gt;
&lt;p&gt;By leveraging MacPorts to install MySQL, maintenance of the software is slightly easier, especially when you want to upgrade over time. We are using MySQL on our development machine as we prefer to have identical software across our environments. Rails 2.0.2, 2.1, and newer uses SQLite by default, which is fine for development and experimentation, but not appropriate for production code.&lt;/p&gt;
&lt;p&gt;To get started, type into your terminal window:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port install mysql5 +server
&lt;/pre&gt;
&lt;p&gt;This command downloads and installs the baseline MySQL client programs and server software. Next, you want to configure MySQL&amp;#8217;s server so it launches when your computer boots up:&lt;/p&gt;
&lt;pre&gt;
	$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;launchctl&lt;/code&gt; is an Apple tool that administers the system daemon that controls the boot process and background programs. Here you are loading the instructions for how to manage MySQL.&lt;/p&gt;
&lt;p&gt;A fresh MySQL installation requires its database storage area to be initialized, so you do that next:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mysql_install_db5 --user=mysql
&lt;/pre&gt;
&lt;p&gt;When you configure the storage area with this command, you&amp;#8217;re making sure it is owned by the user &amp;#8220;mysql&amp;#8221;.&lt;/p&gt;
&lt;p&gt;MySQL creates a special system file used for program to program communication, called the &amp;#8220;socket&amp;#8221; file. By default, the MacPorts installation of MySQL server creates this in the directory &amp;#8220;/opt/local/var/run/mysql5/mysqld.sock&amp;#8221;. Ruby on Rails applications can deal with this just fine if you change the settings in your database.yml file to include a &lt;code&gt;socket&lt;/code&gt; entry that points to the correct place. However, we are going to tweak things so all applications can find the file in a fairly standard place: &lt;strong&gt;/tmp/mysql.sock&lt;/strong&gt; with little or no modification.&lt;/p&gt;
&lt;p&gt;First, you need to move the default configuration file, &lt;code&gt;my.cnf&lt;/code&gt;, to the correct place:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mv /opt/local/etc/my.cnf /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;If the installation program didn&amp;#8217;t put a file into /opt/local/etc/, try this instead:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mv /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;Now, you need to edit the configuration file to change where the socket file is stored:&lt;/p&gt;
&lt;pre&gt;
	$ sudo pico /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;If you aren&amp;#8217;t familiar with the &lt;code&gt;pico&lt;/code&gt; command line editor, we explain the few commands you will need here.&lt;/p&gt;
&lt;p&gt;Inside of &lt;code&gt;pico&lt;/code&gt;, use your arrow keys to move down to the line where you first see &amp;#8220;[client]&amp;#8221; and make the following changes (this is just a small part of the whole file):&lt;/p&gt;
&lt;pre&gt;
	...
	# In this file, you can use all long options that a program supports.
	# If you want to know which options a program supports, run the program
	# with the "--help" option.
	
	[mysqld_safe]
	socket          = /tmp/mysql.sock

	# The following options will be passed to all MySQL clients
	[client]
	#password       = your_password
	port            = 3306
	socket          = /tmp/mysql.sock

	# Here follows entries for some specific programs

	# The MySQL server
	[mysqld]
	port            = 3306
	socket          = /tmp/mysql.sock
	...
&lt;/pre&gt;
&lt;p&gt;You are adding the &amp;#8220;[mysqld_safe]&amp;#8221; section (2 lines) just above &amp;#8220;[client]&amp;#8221; and then changing the two instances of the &amp;quot;socket = &amp;quot; lines in the &amp;#8220;[client]&amp;#8221; and &amp;#8220;[mysqld]&amp;#8221; sections to be &lt;code&gt;/tmp/mysql.sock&lt;/code&gt;. Once done, press &lt;code&gt;Control-X&lt;/code&gt;, answer &lt;code&gt;Y&lt;/code&gt; when asked to save, and press return to accept the default file name (&amp;#8220;my.cnf&amp;#8221;).&lt;/p&gt;
&lt;p&gt;Now you start the server up manually:&lt;/p&gt;
&lt;pre&gt;
	$ cd /opt/local ; sudo /opt/local/lib/mysql5/bin/mysqld_safe &amp;amp;amp;	 
&lt;/pre&gt;
&lt;p&gt;You can confirm that MySQL is running by trying to fire it up:&lt;/p&gt;
&lt;pre&gt;
	$ mysql5 -p -u root
	Welcome to the MySQL monitor.  Commands end with ; or \g.
	Your MySQL connection id is 1
	Server version: 5.0.45 Source distribution

	Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

	mysql&amp;amp;gt; exit
&lt;/pre&gt;
&lt;p&gt;When you reboot your computer, MySQL should start automatically in the future.&lt;/p&gt;
&lt;h3&gt;Gems&lt;/h3&gt;
&lt;p&gt;Tiger requires that you install the base collection of gems you will be using:&lt;/p&gt;
&lt;pre&gt;
	$ sudo gem install rake rails capistrano mongrel mongrel_cluster
&lt;/pre&gt;
&lt;p&gt;All installed gems (including Ruby on Rails and its dependencies, Rake, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.&lt;/p&gt;
&lt;p&gt;The MySQL adapter gem needs to be installed, and it is a little finicky due to our use of MacPorts.&lt;/p&gt;
&lt;p&gt;If you are running Tiger on an Intel processor, use this command (on one line):&lt;/p&gt;
&lt;pre&gt;
	$ ARCHFLAGS="-arch i386" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
&lt;/pre&gt;
&lt;p&gt;and if you are on a PowerPC processor, use this command:&lt;/p&gt;
&lt;pre&gt;
	ARCHFLAGS="-arch ppc" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
&lt;/pre&gt;
&lt;p&gt;Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.&lt;/p&gt;
&lt;h3&gt;Code Editing Tools&lt;/h3&gt;
&lt;p&gt;While you can get by with using a plain text editor like TextEdit, or even Apples Xcode &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;, you will have much high productivity if you use a programming editor that is highly tuned to Ruby on Rails development.&lt;/p&gt;
&lt;p&gt;We use the commercial &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; programmer&amp;#8217;s editor for much of our day to day work. TextMate is highly extensible through a collection of community supplied &amp;#8220;bundles&amp;#8221;. Many add-ons accelerate development by enhancing the editor (for example, adding language specific short cuts to reduce your typing) or by tying in to other utilities, such as Subversion or Rake, to allow you to quickly get tasks done without leaving the editor&amp;#8217;s environment.&lt;/p&gt;
&lt;p&gt;There are a variety of good open source or free programmer editors available too. On the open source side, Leopard comes pre-installed with both vim and emacs. &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; is a very extensible open source editor written in Java. &lt;a href="http://www.barebones.com/products/textwrangler/"&gt;TextWrangler&lt;/a&gt; is a free programmer&amp;#8217;s editor from BareBones.&lt;/p&gt;
&lt;p&gt;Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.&lt;/p&gt;
&lt;p&gt;If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; in our LearningRails courses, but you should check out the numerous &lt;a href="http://www.buildingwebapps.com/topic/26-integrated-development-environments-ides"&gt;other options listed at BuildingWebApps.com&lt;/a&gt;.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=G3wnIIWTXxI:H5pDxfvptBM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=G3wnIIWTXxI:H5pDxfvptBM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=G3wnIIWTXxI:H5pDxfvptBM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=G3wnIIWTXxI:H5pDxfvptBM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/G3wnIIWTXxI" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6455-setting-up-rails-on-tiger-mac</feedburner:origLink></entry>
  <entry>
    <title>Setting up Rails on Leopard (Mac OS X 10.5)</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/-vLrmc3qdmQ/6433-setting-up-rails-on-leopard-mac" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6433-setting-up-rails-on-leopard-mac</id>
    <updated>2008-07-18T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>This guide walks you through setup instructions for preparing a Mac OS X 10.5 (aka Leopard) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.</summary>
    <content type="html">
&lt;p&gt;This guide walks you through setup instructions for preparing a Mac OS X 10.5 (aka Leopard) development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our &lt;a href="/course"&gt;LearningRails online course&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will end up with a development machine with the following baseline components:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Ruby and all basic Ruby utilities&lt;/li&gt;
	&lt;li&gt;Ruby Gems package manager&lt;/li&gt;
	&lt;li&gt;Subversion client&lt;/li&gt;
	&lt;li&gt;Git client&lt;/li&gt;
	&lt;li&gt;Native development tools (Xcode, C compiler)&lt;/li&gt;
	&lt;li&gt;MacPorts native code package manager&lt;/li&gt;
	&lt;li&gt;MySQL database client utilities and server&lt;/li&gt;
	&lt;li&gt;Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL&lt;/li&gt;
	&lt;li&gt;Programmer&amp;#8217;s editor or &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: In the command sequences we illustrate here, command line prompts are shown as a dollar sign (&lt;code&gt;$&lt;/code&gt;).&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;This guide assumes you have a Macintosh computer running the current Leopard operating system with up-to-date System Update patches applied. It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.&lt;/p&gt;
&lt;p&gt;You will need to have access to an Internet connection to complete various download steps.&lt;/p&gt;
&lt;p&gt;You will need to have administrator access to your computer to complete this guide. We will be using the &lt;code&gt;sudo&lt;/code&gt; command to run various command line programs and some of the Mac OS X native installers will also ask you for your password.&lt;/p&gt;
&lt;p&gt;It is helpful if you have access to your operating system installation discs.&lt;/p&gt;
&lt;h2&gt;The Recipe&lt;/h2&gt;
&lt;p&gt;Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.&lt;/p&gt;
&lt;h3&gt;Ruby and Ruby Utilities (irb, ri, rdoc)&lt;/h3&gt;
&lt;p&gt;Leopard comes pre-installed with Ruby 1.8.6 and its associated utilities. You can use these programs as is. To check them out, open a Terminal window and type:&lt;/p&gt;
&lt;pre&gt;
	$ which ruby
	/usr/bin/ruby
	$ ruby -v
	ruby 1.8.6 (2007-09-24 patchlevel 111) [universal-darwin9.0]
&lt;/pre&gt;
&lt;p&gt;You should seem similar responses. The important one is the first one which reports back the path of the Ruby interpreter program. If you are using the built-in Ruby, it will be located in &lt;code&gt;/usr/bin/&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Ruby Gems Package Manager&lt;/h3&gt;
&lt;p&gt;Leopard comes with a pre-installed version of &lt;code&gt;gem&lt;/code&gt;. Be sure you have the latest version:&lt;/p&gt;
&lt;pre&gt;
	$ gem -v
	1.0.1
&lt;/pre&gt;
&lt;p&gt;You need 1.0.1 or newer. If you have an older version, you can update with the command line: &lt;code&gt;sudo gem update --system&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Native Development Tools (Xcode 3.0)&lt;/h3&gt;
&lt;p&gt;You will need a native compiler to build many of the gems&amp;#8217; native libraries you are going to use. You will also occasionally build other native tools via the MacPorts tool described below. Apple provides a free native compiler tool set called Xcode. If you have your Leopard installation &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;, load it now. If you don&amp;#8217;t have an installation &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;, you can download the &lt;a href="http://developer.apple.com/tools/download/"&gt;Xcode 3.0 tools at Apple&amp;#8217;s Developer Web Site&lt;/a&gt;. (Note: Apple developer accounts are free.)&lt;/p&gt;
&lt;p&gt;Open the &lt;code&gt;Optional Installs&lt;/code&gt; folder, and then the &lt;code&gt;Xcode Tools&lt;/code&gt; folder. Double click on the &lt;code&gt;XcodeTools.mpkg&lt;/code&gt; installer and select a standard install. This will take a few minutes to run:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installmac105_xcode.jpg" alt="" /&gt;&lt;/p&gt;
&lt;h3&gt;MacPorts&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; is a native code package manager for Macintosh software. This guide uses MacPorts to setup an installation of MySQL and the Git distributed version control system. There are many other tools available in the MacPorts library, so it is well worth checking out.&lt;/p&gt;
&lt;p&gt;Download the &lt;a href="http://svn.macports.org/repository/macports/downloads/MacPorts-1.6.0/MacPorts-1.6.0-10.5-Leopard.dmg"&gt;Leopard Universal version&lt;/a&gt; (1.6.0 at the time of this writing) and double click the MacPorts &lt;span class="caps"&gt;&lt;span class="caps"&gt;DMG&lt;/span&gt;&lt;/span&gt; file to open it up. Double click on &amp;#8220;MacPorts-1.6.0.pkg&amp;#8221; to start the installer and select the default options.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installmac105_ports.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;After MacPorts completes installation, you need to adjust your command line &lt;code&gt;PATH&lt;/code&gt; environment variable so you can run the &lt;code&gt;port&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Fire up the Terminal program and enter the command:&lt;/p&gt;
&lt;pre&gt;
	$ open .bash_profile
&lt;/pre&gt;
&lt;p&gt;Note that there is a period in front of &amp;#8220;bash_profile&amp;#8221;. The bash shell configuration file should open in the TextEdit program. If you don&amp;#8217;t have a .bash_profile, you can create a new one in your text editor and save it in your home directory.&lt;/p&gt;
&lt;p&gt;(By the way, we recommend &lt;a href="http://iterm.sourceforge.net/"&gt;iTerm&lt;/a&gt; as a nice open source replacement for the Apple Terminal program.)&lt;/p&gt;
&lt;p&gt;Inside of .bash_profile, find the line that starts with &lt;code&gt;export PATH=&lt;/code&gt;, if present. You are going to insert the new directories used by MacPorts into your path:&lt;/p&gt;
&lt;pre&gt;
	export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
&lt;/pre&gt;
&lt;p&gt;If you don&amp;#8217;t have a line that exports your &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt;, use the text exactly as above. If you do already have such a line, add the &lt;code&gt;/opt/local/bin:/opt/local/sbin:&lt;/code&gt; (note colons) after the first quote, but before any other paths. Here is an example:&lt;/p&gt;
&lt;pre&gt;
	export PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:$PATH"
&lt;/pre&gt;
&lt;p&gt;Save the file and close TextEdit. Open a new terminal window and have MacPorts update itself with the command:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port selfupdate
&lt;/pre&gt;
&lt;h3&gt;Installing Git via MacPorts&lt;/h3&gt;
&lt;p&gt;Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. Currently Leopard doesn&amp;#8217;t install git by default, so we&amp;#8217;ll use MacPorts to quickly install git:&lt;/p&gt;
&lt;pre&gt;
 	$ sudo port install git-core +doc +svn
&lt;/pre&gt;
&lt;p&gt;This command installs the core git tools, the man page documentation, and integration with Subversion. This last is useful if you plan on migrating from or need to work with a legacy Subversion repository. The installation will take a while; it has a lot to load.&lt;/p&gt;
&lt;p&gt;Besides your own project version control, you&amp;#8217;ll typically use git when loading Rails 2.1 and various 3rd party plugins.&lt;/p&gt;
&lt;h3&gt;Installing MySQL via MacPorts&lt;/h3&gt;
&lt;p&gt;By leveraging MacPorts to install MySQL, maintenance of the software is slightly easier, especially when you want to upgrade over time. We are using MySQL on our development machine as we prefer to have identical software across our environments. Rails 2.0.2, 2.1 and newer uses SQLite by default, which is fine for development and experimentation, but not appropriate for production code.&lt;/p&gt;
&lt;p&gt;To get started, type into your terminal window:&lt;/p&gt;
&lt;pre&gt;
	$ sudo port install mysql5 +server
&lt;/pre&gt;
&lt;p&gt;This command downloads and installs the baseline MySQL client programs and server software. Next, you want to configure MySQL&amp;#8217;s server so it launches when your computer boots up:&lt;/p&gt;
&lt;pre&gt;
	$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;launchctl&lt;/code&gt; is an Apple tool that administers the system daemon that controls the boot process and background programs. Here you are loading the instructions for how to manage MySQL.&lt;/p&gt;
&lt;p&gt;A fresh MySQL installation requires its database storage area to be initialized, so you do that next:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mysql_install_db5 --user=mysql
&lt;/pre&gt;
&lt;p&gt;When you configure the storage area with this command, you&amp;#8217;re making sure it is owned by the user &amp;#8220;mysql&amp;#8221;.&lt;/p&gt;
&lt;p&gt;MySQL creates a special system file used for program to program communication, called the &amp;#8220;socket&amp;#8221; file. By default, the MacPorts installation of MySQL server creates this in the directory &amp;#8220;/opt/local/var/run/mysql5/mysqld.sock&amp;#8221;. Ruby on Rails applications can deal with this just fine if you change the settings in your database.yml file to include a &lt;code&gt;socket&lt;/code&gt; entry that points to the correct place. However, we are going to tweak things so all applications can find the file in a fairly standard place: &lt;strong&gt;/tmp/mysql.sock&lt;/strong&gt; with little or no modification.&lt;/p&gt;
&lt;p&gt;First, you need to move the default configuration file, &lt;code&gt;my.cnf&lt;/code&gt;, to the correct place:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mv /opt/local/etc/my.cnf /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;If the installation program didn&amp;#8217;t put a file into /opt/local/etc/, try this instead:&lt;/p&gt;
&lt;pre&gt;
	$ sudo mv /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;Now, you need to edit the configuration file to change where the socket file is stored:&lt;/p&gt;
&lt;pre&gt;
	$ sudo pico /opt/local/etc/mysql5/my.cnf
&lt;/pre&gt;
&lt;p&gt;If you aren&amp;#8217;t familiar with the &lt;code&gt;pico&lt;/code&gt; command line editor, we explain the few commands you will need here.&lt;/p&gt;
&lt;p&gt;Inside of &lt;code&gt;pico&lt;/code&gt;, use your arrow keys to move down to the line where you first see &amp;#8220;[client]&amp;#8221; and make the following changes (this is just a small part of the whole file):&lt;/p&gt;
&lt;pre&gt;
	...
	# In this file, you can use all long options that a program supports.
	# If you want to know which options a program supports, run the program
	# with the "--help" option.
	
	[mysqld_safe]
	socket          = /tmp/mysql.sock

	# The following options will be passed to all MySQL clients
	[client]
	#password       = your_password
	port            = 3306
	socket          = /tmp/mysql.sock

	# Here follows entries for some specific programs

	# The MySQL server
	[mysqld]
	port            = 3306
	socket          = /tmp/mysql.sock
	...
&lt;/pre&gt;
&lt;p&gt;You are adding the &amp;#8220;[mysqld_safe]&amp;#8221; section (2 lines) just above &amp;#8220;[client]&amp;#8221; and then changing the two instances of the &amp;quot;socket = &amp;quot; lines in the &amp;#8220;[client]&amp;#8221; and &amp;#8220;[mysqld]&amp;#8221; sections to be &lt;code&gt;/tmp/mysql.sock&lt;/code&gt;. Once done, press &lt;code&gt;Control-X&lt;/code&gt;, answer &lt;code&gt;Y&lt;/code&gt; when asked to save, and press return to accept the default file name (&amp;#8220;my.cnf&amp;#8221;).&lt;/p&gt;
&lt;p&gt;Now you start the server up manually:&lt;/p&gt;
&lt;pre&gt;
	$ cd /opt/local ; sudo /opt/local/lib/mysql5/bin/mysqld_safe &amp;amp;amp;	 
&lt;/pre&gt;
&lt;p&gt;You can confirm that MySQL is running by trying to fire it up:&lt;/p&gt;
&lt;pre&gt;
	$ mysql5 -p -u root
	Welcome to the MySQL monitor.  Commands end with ; or \g.
	Your MySQL connection id is 1
	Server version: 5.0.45 Source distribution

	Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

	mysql&amp;amp;gt; exit
&lt;/pre&gt;
&lt;p&gt;When you reboot your computer, MySQL should start automatically in the future.&lt;/p&gt;
&lt;h3&gt;Gems&lt;/h3&gt;
&lt;p&gt;Leopard conveniently pre-installs the base collection of gems you will be using, but you need to make sure they are up to date:&lt;/p&gt;
&lt;pre&gt;
	$ sudo gem update
&lt;/pre&gt;
&lt;p&gt;All installed gems (including Ruby on Rails and its dependencies, Rake, Capistrano, Mongrel, and Mongrel_Cluster) will get updated.&lt;/p&gt;
&lt;p&gt;The MySQL adapter gem needs to be installed, and it is a little finicky due to our use of MacPorts.&lt;/p&gt;
&lt;p&gt;If you are running Leopard on an Intel processor, use this command (on one line):&lt;/p&gt;
&lt;pre&gt;
	$ ARCHFLAGS="-arch i386" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
&lt;/pre&gt;
&lt;p&gt;and if you are on a PowerPC processor, use this command:&lt;/p&gt;
&lt;pre&gt;
	ARCHFLAGS="-arch ppc" sudo gem install mysql -- --with-mysql-config=/opt/local/bin/mysql_config5
&lt;/pre&gt;
&lt;p&gt;Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.&lt;/p&gt;
&lt;h3&gt;Code Editing Tools&lt;/h3&gt;
&lt;p&gt;While you can get by with using a plain text editor like TextEdit, or even Apple&amp;#8217;s Xcode &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;, you will be more productive if you use a programming editor that is highly tuned to Ruby on Rails development.&lt;/p&gt;
&lt;p&gt;We use the commercial &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; programmer&amp;#8217;s editor for much of our day-to-day work. TextMate is highly extensible through a collection of community supplied &amp;#8220;bundles&amp;#8221;. Many add-ons accelerate development by enhancing the editor (for example, adding language specific short cuts to reduce your typing) or by tying in to other utilities, such as Subversion or Rake, to allow you to quickly get tasks done without leaving the editor&amp;#8217;s environment.&lt;/p&gt;
&lt;p&gt;There are a variety of good open source or free programmer editors available too. On the open source side, Leopard comes pre-installed with both vim and emacs. &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; is a very extensible open source editor written in Java. &lt;a href="http://www.barebones.com/products/textwrangler/"&gt;TextWrangler&lt;/a&gt; is a free programmer&amp;#8217;s editor from BareBones.&lt;/p&gt;
&lt;p&gt;Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.&lt;/p&gt;
&lt;p&gt;If you prefer an all-in-one tool, ook at one of the integrated development environments for Ruby. We use &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; when we aren&amp;#8217;t using TextMate, but the numerous &lt;a href="http://www.buildingwebapps.com/topic/26-integrated-development-environments-ides"&gt;other options listed at BuildingWebApps.com&lt;/a&gt; are worth a look.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=-vLrmc3qdmQ:w5biBk7QbrE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=-vLrmc3qdmQ:w5biBk7QbrE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=-vLrmc3qdmQ:w5biBk7QbrE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=-vLrmc3qdmQ:w5biBk7QbrE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/-vLrmc3qdmQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6433-setting-up-rails-on-leopard-mac</feedburner:origLink></entry>
  <entry>
    <title>Podcasts and Screencasts on Ruby on Rails</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/VLq93QQSm4k/6509-podcasts-and-screencasts-on-ruby-on" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6509-podcasts-and-screencasts-on-ruby-on</id>
    <updated>2008-06-17T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>There's a variety of screencasts and podcasts available for Ruby on Rails developers. Here's a quick rundown of the major ones, and how they differ.</summary>
    <content type="html">
&lt;p&gt;There&amp;#8217;s a variety of screencasts and podcasts available for Ruby on Rails developers. Here&amp;#8217;s a quick rundown of the major ones, and how they differ.&lt;/p&gt;
&lt;h2&gt;Podcasts&lt;/h2&gt;
&lt;p&gt;Audio podcasts are great for listening on the go, and for things such as news and interviews.&lt;/p&gt;
&lt;h3&gt;Tutorial: Learning Rails&lt;/h3&gt;
&lt;p&gt;Our own &lt;a href="/course"&gt;Learning Rails&lt;/a&gt; series consists of 8 podcasts that cover the fundamental concepts behind Ruby on Rails.&lt;/p&gt;
&lt;h3&gt;People: Ruby on Rails Podcast&lt;/h3&gt;
&lt;p&gt;The longest-running podcast in the Rails world is the &amp;#8220;official&amp;#8221; &lt;a href="http://podcast.rubyonrails.org/"&gt;Ruby on Rails podcast&lt;/a&gt;, first created by Scott Barron but produced for most of its life by Geoffrey Grosenbach. This is a great series of interviews with many of the leading developers in the Ruby and Rails world.&lt;/p&gt;
&lt;h3&gt;News: Rails Envy&lt;/h3&gt;
&lt;p&gt;The &lt;a href="http://railsenvy.com/podcast"&gt;Rails Envy podcast&lt;/a&gt; comes out every week and provides a fantastic summary of the latest developments in the Rails world. It&amp;#8217;s put together by Gregg Pollack, Jason Seifer, and Steven Bristol, who diligently track a wide variety of Rails blogs to provide you with a distilled and entertaining weekly update.&lt;/p&gt;
&lt;h2&gt;Screencasts&lt;/h2&gt;
&lt;p&gt;Screencasts let you watch what&amp;#8217;s going on on the screen while the presenter explains what they&amp;#8217;re doing. It&amp;#8217;s like looking over the shoulder of a developer while they work. Screencasts are a great teaching tool.&lt;/p&gt;
&lt;h3&gt;Learning Rails&lt;/h3&gt;
&lt;p&gt;Our &lt;a href="/screencasts"&gt;Learning Rails&lt;/a&gt; screencast series shows how to build a simple web site using Ruby on Rails, step-by-step. Designed for people who are new to Ruby on Rails.&lt;/p&gt;
&lt;h3&gt;Envycasts&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://envycasts.com"&gt;Envycasts&lt;/a&gt; is the latest entrant into the Rails screencasts business. They&amp;#8217;re created by the Rails Envy folks, Gregg Pollack and Jason Seifer, who bring their trademark wit and creative production to advanced technical screencasts. There&amp;#8217;s nothing else like them. Priced at $9 each.&lt;/p&gt;
&lt;h3&gt;Railscasts&lt;/h3&gt;
&lt;p&gt;Ryan Bates has producing more than 100 free &lt;a href="http://railscasts.com"&gt;Railscasts&lt;/a&gt; screencasts. They&amp;#8217;re short episodes focused on a single feature of Rails, and are a great way to learn how to do specific things with Rails.&lt;/p&gt;
&lt;h3&gt;Peepcode&lt;/h3&gt;
&lt;p&gt;Geoffrey Grosenbach&amp;#8217;s &lt;a href="http://peepcode.com"&gt;Peepcode&lt;/a&gt; are the gold standard for Ruby on Rails screencasts. At $9 each, they aren&amp;#8217;t free, but they&amp;#8217;re still a great value. They&amp;#8217;re typically about an hour long and deeply explore specific topics, from Git to rSpec.&lt;/p&gt;
&lt;h3&gt;Pragmatic Screencasts&lt;/h3&gt;
&lt;p&gt;The Pragmatic Programmer, well known for their Ruby and Rails books, has teamed with Mike Clark of Pragmatic Studio, a leading provider of Rails training, to produce the &lt;a href="http://pragmatic.tv"&gt;Pragmatic Screencasts&lt;/a&gt;. The 20 to 30 minutes screencasts cost $5 each. So far, most of them are not about Ruby or Rails, but there is a series by Ryan Bates on &amp;#8220;Everyday Active Record.&amp;#8221;&lt;/p&gt;
&lt;h3&gt;RubyPlus&lt;/h3&gt;
&lt;p&gt;Bala Paranj has produce more than 70 free screencasts on various Ruby and Ruby on Rails techniques at &lt;a href="http://rubyplus.org"&gt;RubyPlus.org&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Coderpath&lt;/h3&gt;
&lt;p&gt;Miles K. Forrest recorded a few early Rails screencasts at &lt;a href="http://coderpath.com"&gt;coderpath&lt;/a&gt; a couple years ago. He&amp;#8217;s been quiet since, but he&amp;#8217;s talking about restarting the series.&lt;/p&gt;
&lt;h3&gt;Zenunit Sensei&lt;/h3&gt;
&lt;p&gt;A short series of Rails screencasts, free for now with some talk of paid screencasts in the future, at &lt;a href="http://sensei.zenunit.com/"&gt;Zenunit Sensei&lt;/a&gt;. From Australia, apparently by Julian Leviston.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=VLq93QQSm4k:IhB5N5Cop2U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=VLq93QQSm4k:IhB5N5Cop2U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=VLq93QQSm4k:IhB5N5Cop2U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=VLq93QQSm4k:IhB5N5Cop2U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/VLq93QQSm4k" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6509-podcasts-and-screencasts-on-ruby-on</feedburner:origLink></entry>
  <entry>
    <title>The Rebuilding and Scaling of YellowPages.com</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/74nS0ZOgZWk/6512-the-rebuilding-and-scaling-of-yellowpages-com" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6512-the-rebuilding-and-scaling-of-yellowpages-com</id>
    <updated>2008-06-01T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>John Straw, chief software architect at YellowPages.com, gave an excellent talk at RailsConf about YellowPages' conversion to Rails. John's talk covered the scaling issues, but the talk was just as much about the process of successfully doing a big rewrite of a critical application at a large company.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width: 210px'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/johnstraw.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;John Straw, chief software architect at &lt;a href="http://www.yellowpages.com"&gt;YellowPages.com&lt;/a&gt;, gave an excellent talk at RailsConf about YellowPages&amp;#8217; conversion to Rails. We&amp;#8217;ve pointed to YellowPages in the past as being one of the highest-traffic Rails sites, proving that &lt;a href="/articles/13-can-rails-scale-absolutely"&gt;Rails can scale&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;John&amp;#8217;s talk covered the scaling issues, but the talk was just as much about the process of successfully doing a big rewrite of a critical application at a large company. (YellowPages.com is part of AT&amp;amp;T.)&lt;/p&gt;
&lt;p&gt;You can &lt;a href="http://en.oreilly.com/rails2008/public/asset/attachment/2765"&gt;download John&amp;#8217;s presentation&lt;/a&gt; from the RailsConf site.&lt;/p&gt;
&lt;p&gt;With 2.5M searches per day and more than 170 million page views per month, YellowPages.com is now the biggest site AT&amp;amp;T runs, generating more traffic than att.com.&lt;/p&gt;
&lt;h2&gt;Why the rewrite?&lt;/h2&gt;
&lt;p&gt;The previous version was written in Java in 2004 and 2005 by consultants, and had fundamental design problems. This version had 125K lines of code and no automated tests, making new features hard to implement. The Rails version ended up with fewer than 20K lines of code, including tests.&lt;/p&gt;
&lt;p&gt;The Java site also had lots of usability issues and &lt;span class="caps"&gt;&lt;span class="caps"&gt;SEO&lt;/span&gt;&lt;/span&gt; problems. As an example of the difficulty of adding features, John noted that it took three months to add a rating feature.&lt;/p&gt;
&lt;p&gt;The requirements for the new version included:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Absolute control of URLs&lt;/li&gt;
	&lt;li&gt;No sessions&lt;/li&gt;
	&lt;li&gt;Be agile&lt;/li&gt;
	&lt;li&gt;Develop easy-to-leverage core business services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The new product was built by a cross-functional team of 20 people, including project managers, user experience experts, advertising people, search experts, and content and community managers. There were never more than 5 developers. The entire team sat together for the duration of the project.&lt;/p&gt;
&lt;p&gt;The architecture they designed has three tiers: a web tier that delivers the front-end web experience; a services tier that responds to requests from the web tier; and a search cluster that performs the actual searches.&lt;/p&gt;
&lt;p&gt;The team built an initial Rails prototype in early 2007 that looked like the existing site, just to get some experience with Rails. (Only one of the team members had any prior Rails experience.) They also built prototype search code in Python. They then started a new Rails prototype with designs from user experience team. They also built a Django prototype to explore that option, and evaluated EJB3/JBoss as a service tier platform.&lt;/p&gt;
&lt;h2&gt;Why Rails?&lt;/h2&gt;
&lt;p&gt;The team rejected Java for the front end in part because of its inadequate &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; control. In terms of Rails vs. Django, John called the decision a near toss-up. Platform maturity was an important attribute that led them to choose Rails. They also felt that it had better automated testing integration and a clearer path to moving parts of it to C if necessary for performance. Ultimately, the development team simply felt more comfortable with it.&lt;/p&gt;
&lt;p&gt;John had initially expected they would use Java for the service tier, but after an evaluation of EJB3 the team felt there were no real advantages over Ruby or Python for their application. All the reasons for choosing Rails for the web tier applied equally to service tier, and having a single software environment has obvious advantages.&lt;/p&gt;
&lt;h2&gt;Keeping the project moving&lt;/h2&gt;
&lt;p&gt;The success of this rewrite had as much to do with adeptly managing the process as with technology. One key to keeping it moving was giving one person decision-making authority. Another important factor was freezing development on the existing site, so they wouldn&amp;#8217;t have a moving target. An ad-hoc rule they came up with was that if you can&amp;#8217;t figure out quickly how you&amp;#8217;d like to change something about the existing site, then don&amp;#8217;t change it.&lt;/p&gt;
&lt;p&gt;Another important process was early and frequent communication with the sales team. A previous site redesign had nearly failed because of lack of support from sales. The project lead, who came from the user experience team, met with 20 to 40 salespeople a week to review the proposed changes. This gave them the buy-in they needed for the site to be successful from a business perspective.&lt;/p&gt;
&lt;p&gt;The site was made available to friends and family as a closed beta on 4/26/07, an open beta on 5/17/07, and then went live at the end of June, less than six months after beginning work on their first Rails prototype. This was the first time AT&amp;amp;T had released a beta of any kind.&lt;/p&gt;
&lt;p&gt;A few things were farmed out to other teams, including &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;/&lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; coding, rewrite rules for legacy &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; translation, and performance evaluation for the production deployment configuration.&lt;/p&gt;
&lt;h2&gt;System architecture&lt;/h2&gt;
&lt;p&gt;The web tier, service tier, and search cluster are each fronted by an &lt;a href="http://www.f5.com/products/big-ip/"&gt;F5 load balancer&lt;/a&gt;. The web tier initially used Apache with 16 Mongrels on each server, while the service tier uses Apache with 30 Mongrels and memcached on each server.&lt;/p&gt;
&lt;p&gt;The communication between tiers uses stateless &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; transactions. The service tier provides a set of RESTful services that return &lt;span class="caps"&gt;&lt;span class="caps"&gt;JSON&lt;/span&gt;&lt;/span&gt; to the web tier. The search cluster uses the &lt;a href="http://www.fastsearch.com/l3a.aspx?m=1031"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;FAST&lt;/span&gt;&lt;/span&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;ESP&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; search engine.&lt;/p&gt;
&lt;p&gt;The entire system consists of 25 machines, each with two dual-core, 64-bit processors. Two of the 25 are used for the database. This compares to 21 servers for the previous Java-based solution. There are two data centers with identical setups; each is designed to handle the entire load, so they provide geographically distributed redundancy.&lt;/p&gt;
&lt;p&gt;They run Solaris on the database machines and CentOS 5 on all the others. John called Solaris &amp;#8220;a mistake they wouldn&amp;#8217;t repeat,&amp;#8221; not because of any particular problems with it but because of a lack of system administrators in their organization who had experience with it.&lt;/p&gt;
&lt;p&gt;They use Oracle for the database engine, which had issues with the large numbers of connections created by the large number of Mongrels. As a result, memory usage on the database servers was high, and these machines were upgraded to 12G of &lt;span class="caps"&gt;&lt;span class="caps"&gt;RAM&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h2&gt;Performance optimization&lt;/h2&gt;
&lt;p&gt;The performance goals, which were achieved, were:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Sub-second home page load time&lt;/li&gt;
	&lt;li&gt;4-second average search time&lt;/li&gt;
	&lt;li&gt;Never dies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the course of performance optimization, they considered &lt;a href="http://haproxy.1wt.eu/"&gt;HAProxy&lt;/a&gt; and &lt;a href="http://swiftiply.swiftcore.org/"&gt;Swiftiply&lt;/a&gt; but chose to go with the F5 because they had the hardware and understood how to use it.&lt;/p&gt;
&lt;p&gt;They wrote Mongrel handlers to pick requests off from the web tier and send them to the service tier without involving Rails. They also wrote a C library for parsing search cluster responses and turning them into hashes.&lt;/p&gt;
&lt;p&gt;In the web tier, they switched to &lt;a href="http://www.kuwata-lab.com/erubis/"&gt;Erubis&lt;/a&gt; for rendering views. They found asset download times to be a bigger issue than the speed of the framework. Following the Yahoo performance guidelines, they minified the JavaScript. They also switched from Prototype to jQuery.&lt;/p&gt;
&lt;p&gt;They used the asset_packager plug-in (now made obsolete by Rails 2) and moved image serving to an &lt;a href="http://www.akamai.com/html/solutions/media_delivery.html"&gt;Akamai&lt;/a&gt; edge cache.&lt;/p&gt;
&lt;p&gt;They found that Apache was slow serving the 42-byte single-pixel GIFs that they use as analytics tags, which drove a shift to &lt;a href="/topic/156-nginx"&gt;Nginx&lt;/a&gt; for the web tier.&lt;/p&gt;
&lt;p&gt;After this tuning, performance was better than the Java site. In terms of availability, all site availability issues in first six months were due to database problems.&lt;/p&gt;
&lt;p&gt;All things considered, it was a very successful rewrite. While the problems with the prior Java site cannot all be blamed on the technology, it is clear that Rails gave the team significant advantages with no loss of performance.&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=74nS0ZOgZWk:RXW2Z21_9_c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=74nS0ZOgZWk:RXW2Z21_9_c:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=74nS0ZOgZWk:RXW2Z21_9_c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=74nS0ZOgZWk:RXW2Z21_9_c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/74nS0ZOgZWk" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6512-the-rebuilding-and-scaling-of-yellowpages-com</feedburner:origLink></entry>
  <entry>
    <title>New Crop of Rails 2.0 Books</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/qdDLxnJAfOk/6508-new-crop-of-rails-2-0-books" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6508-new-crop-of-rails-2-0-books</id>
    <updated>2008-05-28T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>In 2007, more than a dozen Ruby on Rails books debuted &amp;#8212; only to be almost instantly made out-of-date by the release of Rails 2 toward the end of the year. There are now some great Rails 2.0 books out, making life a lot easier for new and experienced Ruby on Rails programmers.</summary>
    <content type="html">
&lt;p&gt;In 2007, more than a dozen Ruby on Rails books debuted &amp;#8212; only to be almost instantly made out-of-date by the release of Rails 2 toward the end of the year. In many respects, books written for Rails 1.2 are usable with Rails 2.0, but they can be problematic. If they use the scaffold generator in their examples, or dynamic scaffolding, the examples simply won&amp;#8217;t work as written. And there are many small ways, such as the enhanced syntax for migrations, in which a Rails 1.2 book will teach a way that works, but is no longer optimal.&lt;/p&gt;
&lt;p&gt;There are now some great Rails 2.0 books out, making life a lot easier for new and experienced Ruby on Rails programmers. Here&amp;#8217;s a quick rundown of the recent books.&lt;/p&gt;
&lt;h3&gt;For Beginners&lt;/h3&gt;
&lt;p&gt;If you&amp;#8217;re new to Rails and don&amp;#8217;t have a lot of programming experience, Patrick Lenz&amp;#8217;s &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0980455200/buildicom-20"&gt;Simply Rails 2&lt;/a&gt; provides a great start. It explains all the concepts clearly and doesn&amp;#8217;t assume much software development background. The example site built throughout the book is a Digg clone, which serves well to illustrate all the key topics.&lt;/p&gt;
&lt;h3&gt;Getting Started with Rails, for Experienced Developers&lt;/h3&gt;
&lt;p&gt;If you have some web application and object-oriented programming experience, then you may want a book that goes deeper and explains things more fully, but doesn&amp;#8217;t take time to explain programming basics. Agile Web Development with Rails, which was for some time the &lt;em&gt;only&lt;/em&gt; Rails book, is a great book for developers with some experience.&lt;/p&gt;
&lt;p&gt;The second edition of this book, which is the newest available in print, is based on Rails 1.2, and the nicely detailed &amp;#8220;Depot&amp;#8221; shopping-cart example fails under Rails 2.0. The depth of this book also creates many places where the differences between the versions is significant.&lt;/p&gt;
&lt;p&gt;Fortunately, the third edition is now available as a &lt;a href="http://pragprog.com/titles/rails3/agile-web-development-with-rails-third-edition"&gt;beta book&lt;/a&gt;. You can download today&amp;#8217;s version as a &lt;span class="caps"&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt;&lt;/span&gt; file, in which most of the critical updates have already been made, which comes with frequent updates, and also pre-order a printed copy so you&amp;#8217;ll have one as soon it comes out the fall.&lt;/p&gt;
&lt;h3&gt;Going Deeper&lt;/h3&gt;
&lt;p&gt;After a slew of tutorial books in 2007, most of which are written for Rails 1.2, there&amp;#8217;s been a recent surge in deeper, more advanced books that add a tremendous richness to the available Rails books.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321445619/buildicom-20"&gt;The Rails Way&lt;/a&gt; is great reference work for Rails developers. It is not a book to start with, but it&amp;#8217;s one I&amp;#8217;d want to have by my side for reference once I had my bearings.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0978739221/buildicom-20"&gt;Advanced Rails Recipes&lt;/a&gt; includes dozens of short, focused articles explaining how to accomplish a particular Rails task. There&amp;#8217;s a tremendous amount of accumulated community knowledge in this book, which was written by Mike Clark with contributions from many people in the community.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/1590599942/buildicom-20"&gt;Practical &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt; on Rails 2 Projects&lt;/a&gt;, by Ben Scofield, is the first book to deeply explore the use of RESTful web services as implemented in Rails 2. It even includes an example of a Facebook application.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0978739205/buildicom-20"&gt;Deploying Rails Applications&lt;/a&gt; is the first book to really tackle Rails deployment in all of its complexities. With a cast of authors that includes Ezra Zygmuntowicz, Bruce Tate, Clinton Begin, Geoffrey Grosenbach, and Brian Hogan, this book encapsulates a lot of hard-earned knowledge and will save a lot of people a lot of pain.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=qdDLxnJAfOk:KYE2ajPtlsw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=qdDLxnJAfOk:KYE2ajPtlsw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=qdDLxnJAfOk:KYE2ajPtlsw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=qdDLxnJAfOk:KYE2ajPtlsw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/qdDLxnJAfOk" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6508-new-crop-of-rails-2-0-books</feedburner:origLink></entry>
  <entry>
    <title>Easy Text Formatting with Textile</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/O2ndlM0eliA/6399-easy-text-formatting-with-textile" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6399-easy-text-formatting-with-textile</id>
    <updated>2008-05-09T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>HTML is rather verbose as a markup language, and having to include closing tags is messy and error-prone. We're all pretty much stuck with delivering HTML code from our web sites, but that doesn't mean we have to write in it. There are various markup approaches that are superior to HTML when it comes to content creation, and which can be used as source code from which to create HTML. Two that are widely used are ...</summary>
    <content type="html">
&lt;p&gt;When I&amp;#8217;m writing content for the web, I hate dealing with &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; coding. &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; is rather verbose as a markup language, and having to include closing tags is messy and error-prone.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re all pretty much stuck with delivering &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; code from our web sites, but that doesn&amp;#8217;t mean we have to write in it. There are various markup approaches that are superior to &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; when it comes to content creation, and which can be used as source code from which to create &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;. Two that are widely used are Textile and Markdown.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://textism.com/tools/textile/"&gt;Textile&lt;/a&gt; was originally developed by Dean Allen for the TextPattern content management system and is now widely used in wikis and blogs. &lt;a href="http://daringfireball.net/projects/markdown/basics"&gt;Markdown&lt;/a&gt;, created by John Gruber and Aaron Swartz, is an alternative that is conceptually similar but with a different syntax. Many of the popular blog engines provide a choice of Textile or Markdown (or &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;) for posts and comments (this site offers Textile).&lt;/p&gt;
&lt;p&gt;In this article, I&amp;#8217;ll show the basics of Textile markup and how easy it is to use it in Rails applications.&lt;/p&gt;
&lt;h1&gt;What is Textile?&lt;/h1&gt;
&lt;p&gt;Textile strives to make text markup as clean and simple as possible. You don&amp;#8217;t have to put &lt;code&gt;&amp;amp;lt;p&amp;amp;gt;&lt;/code&gt; in front of each paragraph; bare text is automatically surrounded by &lt;code&gt;&amp;amp;lt;p&amp;amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;amp;lt;/p&amp;amp;gt;&lt;/code&gt; tags. To make a first-level heading, just start the line with @h1. @. For example:&lt;/p&gt;
&lt;pre&gt;
h1. This is a heading and will be wrapped in &amp;amp;lt;h1&amp;amp;gt; and &amp;amp;lt;/h1&amp;amp;gt; tags

This is a text paragraph and will be wrapped in &amp;amp;lt;p&amp;amp;gt; and &amp;amp;lt;/p&amp;amp;gt; tags.

This is another paragraph.
&lt;/pre&gt;
&lt;p&gt;And I bet you can guess how to make a second-level heading, or a third-level heading.&lt;/p&gt;
&lt;p&gt;You never need to use close tags; a pair of carriage returns automatically triggers the appropriate end tag. Quotes are automatically converted to open and close quotes; hyphens are converted to n-dashes (if there is a space on either side); and double hyphens are converted to m-dashes.&lt;/p&gt;
&lt;p&gt;To make text bold, surround it with asterisks; to make it italic, with underscores:&lt;/p&gt;
&lt;pre&gt;
*This text will render in bold*
_This text will render in italic*
_*This text will render in bold italic*_
&lt;/pre&gt;
&lt;p&gt;To add a link to a piece of text, surround the text in quotes, and follow it by a colon and the &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;pre&gt;
"text to be linked":http://thisistheurl.com
&lt;/pre&gt;
&lt;p&gt;To include an image, type its &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; surrounded by exclamation points:&lt;/p&gt;
&lt;pre&gt;
!http://domain.com/path/to/image.jpg!
&lt;/pre&gt;
&lt;p&gt;To create a bullet list, start each line with an asterisk and a space, like this:&lt;/p&gt;
&lt;pre&gt;
* First item
* Second item
* Third item
&lt;/pre&gt;
&lt;p&gt;Want a nested bullet list? Just indent the asterisk by three spaces.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s more, but this should give you a feel for it. You can also use any &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; you want for things that Textile doesn&amp;#8217;t cover &amp;#8212; &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; code is simply passed through. For more details, see the &lt;a href="http://hobix.com/textile/"&gt;Textile Reference&lt;/a&gt;. You can try out Textile online at the &lt;a href="http://www.textism.com/tools/textile/"&gt;Textile home page&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Implementing Textile&lt;/h1&gt;
&lt;p&gt;There are Textile implementations for various environments. In my case, using Ruby on Rails, Textile is implemented by &lt;a href="http://whytheluckystiff.net"&gt;whytheluckystiff&lt;/a&gt; &amp;#8217;s &lt;a href="http://whytheluckystiff.net/ruby/redcloth/"&gt;RedCloth&lt;/a&gt; gem. (The current implementation does have some flaws, and a much-enhanced version called &lt;a href="http://code.whytheluckystiff.net/redcloth/wiki/SuperRedCloth"&gt;Super RedCloth&lt;/a&gt; is in development.) To install, just enter the following in the console:&lt;/p&gt;
&lt;pre&gt;
gem install RedCloth
&lt;/pre&gt;
&lt;p&gt;With RedCloth installed, you create a new RedCloth object and pass some Textile-marked-up text to it:&lt;/p&gt;
&lt;pre&gt;
textile_styled_text ="h1. This is an example of a heading in Textile"
textile_object = RedCloth.new(textile_styled_text)
&lt;/pre&gt;
&lt;p&gt;Then, when you want to render this as &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;, you simply use:&lt;/p&gt;
&lt;pre&gt;
html = textile_object.to_html
&lt;/pre&gt;
&lt;h1&gt;Making Textile Even Easier&lt;/h1&gt;
&lt;p&gt;That&amp;#8217;s pretty easy, but you can make it even easier. There&amp;#8217;s a Rails helper &amp;#8220;textilize,&amp;#8221; but thanks to  the &lt;a href="http://errtheblog.com/post/14"&gt;acts_as_textiled&lt;/a&gt; plug from Chris Wanstrath, it&amp;#8217;s even easier than that. Install this plugin:&lt;/p&gt;
&lt;pre&gt;
ruby script/plugin install
 svn://errtheblog.com/svn/plugins/acts_as_textiled
&lt;/pre&gt;
&lt;p&gt;And then all you have to do is declare a model attribute as Textile-formatted in your model class:&lt;/p&gt;
&lt;pre&gt;
acts_as_textiled  :field_name
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s it &amp;#8212; everything just works! (Remember, though, that you need to restart the server for the model change to take effect.) Textile marked up text is stored in the database. Form fields automatically show unrendered textile. But any other use of the model attribute automatically delivers the rendered &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; instead of the Textile source.&lt;/p&gt;
&lt;h1&gt;Markup without Coding&lt;/h1&gt;
&lt;p&gt;You can also simplify the entry of Textile markup by using the &lt;a href="http://slateinfo.blogs.wvu.edu/plugins/textile_editor_helper"&gt;textile_editor_helper&lt;/a&gt; from Dave Olsen and Chris Scharf. This plug-in renders a set of icons for the common markup tasks in your form view, just above the text entry area:&lt;/p&gt;
&lt;p&gt;&lt;img src="/textile_helper.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;When you click an icon, JavaScript code inserts the appropriate markup into your text.&lt;/p&gt;
&lt;p&gt;To use this, first install the plugin:&lt;/p&gt;
&lt;pre&gt;
ruby script/plugin install
 http://svn.webtest.wvu.edu/repos/rails/plugins/textile_editor_helper

rake textile_editor_helper:install
&lt;/pre&gt;
&lt;p&gt;And then replace the text_area tag in the form in which the user enters the Textile-formatted text with textile_editor:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;%= textile_editor 'object', 'field' -%&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;textile_editor takes all the same options as text_area.&lt;/p&gt;
&lt;p&gt;and at the end of the form add:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;%= textile_editor_initialize -%&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;Finally, if you don&amp;#8217;t already include prototype.js, you&amp;#8217;ll need to add that to your layout:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;%= javascript_include_tag 'prototype.js' %&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;Presto! Now you have a row of icons above the text area so your users don&amp;#8217;t have to remember any markup at all. They&amp;#8217;ll still see the markup in the text area (this is not a wysiwyg editor), which will help them learn the markup code.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=O2ndlM0eliA:hNI9LBH75bE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=O2ndlM0eliA:hNI9LBH75bE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=O2ndlM0eliA:hNI9LBH75bE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=O2ndlM0eliA:hNI9LBH75bE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/O2ndlM0eliA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6399-easy-text-formatting-with-textile</feedburner:origLink></entry>
  <entry>
    <title>Web 2.0 Expo Highlights and Factoids</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/c9LNVr12_9E/6507-web-2-0-expo-highlights-and-factoids" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6507-web-2-0-expo-highlights-and-factoids</id>
    <updated>2008-04-28T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Last week's Web 2.0 Expo had an overwhelming amount of content. Like any large conference, the quality was uneven, but there were some great talks and a lot of good ones. Here's some highlights and random factoids about AIM, Ning, WordPress, and MySpace.</summary>
    <content type="html">
&lt;p&gt;Last week&amp;#8217;s Web 2.0 Expo had an overwhelming amount of content. Like any large conference, the quality was uneven, but there were some great talks and a lot of good ones. Among the main-session talks, &lt;a href="http://www.shirky.com/"&gt;Clay Shirky&lt;/a&gt; gave a wonderful talk on the implications of the web. I especially liked his view on the &amp;#8220;cognitive surplus&amp;#8221; created by the shift from rural to urban lifestyles, and how this has historically been consumed by alcohol, and then by television. Now this cognitive surplus fuels wikipedia, and all the other forms of user participation on the web. Where does the time come from? Just a fraction of the time spent watching television.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://blip.tv/file/855937"&gt;Video of Clay&amp;#8217;s talk&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.shirky.com/herecomeseverybody/2008/04/looking-for-the-mouse.html"&gt;Transcript of Clay&amp;#8217;s talk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;m halfway through his new book, &lt;a href="http://www.amazon.com/exec/obidos/ASIN/1594201536/buildicom-20"&gt;Here Comes Everybody: The Power of Organizing without Organizations&lt;/a&gt;, and it promises to be a worthwhile read.&lt;/p&gt;
&lt;p&gt;The most entertaining talk of the conference, by a long shot, was from &lt;a href="http://fakesteve.blogspot.com/"&gt;Fake Steve Jobs&lt;/a&gt;, also known as Dan Lyons in his day job at Forbes. The &lt;a href="http://fakesteve.blogspot.com/"&gt;Secret Diary of Steve Jobs&lt;/a&gt; is one of the best pieces of technology satire around.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://blip.tv/file/858285"&gt;Video of Dan&amp;#8217;s talk at Web 2.0&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://web2expo.blip.tv/#864781"&gt;Videos of all the other keynote presentations&lt;/a&gt; are also available.&lt;/p&gt;
&lt;p&gt;Among the most technical talks, and the only one with any real Ruby on Rails content, was Gregg Pollack&amp;#8217;s excellent talk on &lt;a href="http://www.railsenvy.com/ArtOfTestingWebApplications.pdf"&gt;The Art of Testing Web Applications&lt;/a&gt;. (We proposed several Rails-related talks, but they didn&amp;#8217;t make the cut; apparently the organizers chose to avoid most technology-specific talks this year.)&lt;/p&gt;
&lt;p&gt;Many of the &lt;a href="http://en.oreilly.com/webexsf2008/public/schedule/proceedings"&gt;presentation files&lt;/a&gt; have been posted, and more are likely to be added soon.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an assortment of random factoids from my notes:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;70% of &lt;a href="http://current.com"&gt;current.com&lt;/a&gt; users are on their computer at the same time they&amp;#8217;re watching TV&lt;/li&gt;
	&lt;li&gt;There&amp;#8217;s 2.43 billion photos on &lt;a href="http://flickr.com"&gt;flickr&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;28 million people a month share a video on &lt;a href="http://youtube.com"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;MySQL is downloaded 70,000 times a day&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://aim.com"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;AIM&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; stats:&lt;br /&gt;
	&lt;ul&gt;&lt;br /&gt;
		&lt;li&gt;Delivers 2 billion instant messages every day&lt;/li&gt;
		&lt;li&gt;Has had as many as 14 million simultaneous users&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;AIM&lt;/span&gt;&lt;/span&gt; sees a usage drop when there&amp;#8217;s a popular show on TV, and then a peak when it ends&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://ning.com"&gt;Ning&lt;/a&gt; stats:&lt;br /&gt;
	&lt;ul&gt;&lt;br /&gt;
		&lt;li&gt;Ning has about 250,000 individual social networks&lt;/li&gt;
		&lt;li&gt;70% of the networks are active (used in last 30 days)&lt;/li&gt;
		&lt;li&gt;Adding 1 million registered users per month&lt;/li&gt;
		&lt;li&gt;Adding 1,500 new networks a day&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://myspace.com"&gt;MySpace&lt;/a&gt; stats:&lt;br /&gt;
	&lt;ul&gt;&lt;br /&gt;
		&lt;li&gt;117M unique users last month&lt;/li&gt;
		&lt;li&gt;100 billion rows of data in the database&lt;/li&gt;
		&lt;li&gt;85 gigs of bandwidth&lt;/li&gt;
		&lt;li&gt;5 million concurrent users&lt;/li&gt;
		&lt;li&gt;200K to 400K new users per day&lt;/li&gt;
		&lt;li&gt;11% of all on-line minutes are spent on myspace&lt;/li&gt;
		&lt;li&gt;50 million messages sent per day&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://wordpress.com"&gt;WordPress&lt;/a&gt; stats:&lt;br /&gt;
	&lt;ul&gt;&lt;br /&gt;
		&lt;li&gt;54 million unique visitors in the U.S. each month &amp;#8212; one in four people&lt;/li&gt;
		&lt;li&gt;99.999% of WordPress blogs receive under 10,000 pageviews a day&lt;/li&gt;
		&lt;li&gt;In aggregate, there are 10+ million pageviews a day to permalink pages (45% of traffic)&lt;/li&gt;
		&lt;li&gt;An amount of content equivalent to 1.5 wikipedias is created on WordPress each month&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=c9LNVr12_9E:el5S9Xhh57s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=c9LNVr12_9E:el5S9Xhh57s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=c9LNVr12_9E:el5S9Xhh57s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=c9LNVr12_9E:el5S9Xhh57s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/c9LNVr12_9E" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6507-web-2-0-expo-highlights-and-factoids</feedburner:origLink></entry>
  <entry>
    <title>Tim Bray: Ruby is the Leading Language for Web Applications</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/66RF50I2dRo/6505-tim-bray-ruby-is-the-leading" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6505-tim-bray-ruby-is-the-leading</id>
    <updated>2008-04-24T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>In his keynote talk at the recent Silicon Valley Ruby Conference, Sun's Tim Bray asserted that "PHP and Ruby are the languages of choice for new web apps." Coming from most people, this wouldn't be a remarkable comment, but given that Tim is Sun's director of web technologies, it is worthy of note.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width:210px'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/tim_bray.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In his keynote talk at the recent Silicon Valley Ruby Conference, Sun&amp;#8217;s &lt;a href="http://www.tbray.org/ongoing/misc/Tim"&gt;Tim Bray&lt;/a&gt; asserted that &lt;strong&gt;&amp;#8220;&lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; and Ruby are the languages of choice for new web apps.&amp;#8221;&lt;/strong&gt; Coming from most people, this wouldn&amp;#8217;t be a remarkable comment, but given that Tim is Sun&amp;#8217;s director of web technologies, it is worthy of note. Java wasn&amp;#8217;t even on Tim&amp;#8217;s list, much less his recommended solution.&lt;/p&gt;
&lt;p&gt;Tim raised two major concerns about &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt;: security and maintainability. He also pointed out that the object-oriented features &amp;#8220;seem bolted on,&amp;#8221; and don&amp;#8217;t feel right as compared to Ruby. He did note that there are some great &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; applications, such as &lt;a href="http://www.mediawiki.org"&gt;MediaWiki&lt;/a&gt;, &lt;a href="http://wordpress.com/"&gt;WordPress&lt;/a&gt;, and &lt;a href="http://drupal.org"&gt;Drupal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tim asserted that Rails is ahead of Java in terms of maintainability because you have so much less code. And, of course, Rails is best for time to market, which can be all-important to the success of a project.&lt;/p&gt;
&lt;p&gt;As for when to avoid Rails, Tim cited these situations:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;If the IT group will only deploy Java or .&lt;span class="caps"&gt;&lt;span class="caps"&gt;NET&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;When you need a lot of experienced developers quickly&lt;/li&gt;
	&lt;li&gt;If you have a complex database schema you don&amp;#8217;t control&lt;/li&gt;
	&lt;li&gt;For an application that does a lot of computation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tim asserted that &amp;#8220;waterfall development just doesn&amp;#8217;t work any more.&amp;#8221; Some principles for success he cited:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Be human&lt;/li&gt;
	&lt;li&gt;Update often&lt;/li&gt;
	&lt;li&gt;Link&lt;/li&gt;
	&lt;li&gt;Don&amp;#8217;t try to be sticky&lt;/li&gt;
	&lt;li&gt;Look good&lt;/li&gt;
	&lt;li&gt;Balance hubris and humility&lt;/li&gt;
	&lt;li&gt;Free the conversation&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=66RF50I2dRo:NIY3vQrVlRA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=66RF50I2dRo:NIY3vQrVlRA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=66RF50I2dRo:NIY3vQrVlRA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=66RF50I2dRo:NIY3vQrVlRA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/66RF50I2dRo" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6505-tim-bray-ruby-is-the-leading</feedburner:origLink></entry>
  <entry>
    <title>Setting up Rails on Windows XP</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/RIcFcyWgCns/6467-setting-up-rails-on-windows-xp" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6467-setting-up-rails-on-windows-xp</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>This guide walks you through setup instructions for preparing a Windows XP development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.</summary>
    <content type="html">
&lt;p&gt;This guide walks you through setup instructions for preparing a Windows XP development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our &lt;a href="/course"&gt;LearningRails online course&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will end up with a development machine with the following baseline components:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Ruby and all basic Ruby utilities&lt;/li&gt;
	&lt;li&gt;Ruby Gems package manager&lt;/li&gt;
	&lt;li&gt;Subversion client&lt;/li&gt;
	&lt;li&gt;MySQL database client utilities and server&lt;/li&gt;
	&lt;li&gt;Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL&lt;/li&gt;
	&lt;li&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; Terminal Program&lt;/li&gt;
	&lt;li&gt;Git client (&lt;span class="caps"&gt;&lt;span class="caps"&gt;UPDATED&lt;/span&gt;&lt;/span&gt;)&lt;/li&gt;
	&lt;li&gt;Programmer&amp;#8217;s editor or &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: In the command sequences we illustrate here, command line prompts are shown as &lt;code&gt;C:\&amp;amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;This guide assumes you have a Windows computer running the current Windows XP operating system with up-to-date service patches applied (SP2 or higher). It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.&lt;/p&gt;
&lt;p&gt;You will need to have access to an Internet connection to complete various download steps.&lt;/p&gt;
&lt;p&gt;You will need to have administrator access to your computer to complete this guide. Some of the Windows installers may ask you for your password.&lt;/p&gt;
&lt;h2&gt;The Recipe&lt;/h2&gt;
&lt;p&gt;Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.&lt;/p&gt;
&lt;h3&gt;Ruby and Ruby Utilities (irb, ri, rdoc)&lt;/h3&gt;
&lt;p&gt;The &lt;a href="http://rubyforge.org/projects/rubyinstaller/"&gt;One-Click Ruby Installer&lt;/a&gt; does a lot of work for you by installing Ruby, Ruby Gems Package Manager, Rake, all of the other standard Ruby tools, and even the open source SciTE programmer&amp;#8217;s editor. Additionally, the installer configures the command line interface path information, so the Ruby tools are ready to use in the Command Prompt program.&lt;/p&gt;
&lt;p&gt;Download the latest installer (1.8.6 r26 as of this writing) and double click on it to get started.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_1click.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Select all of the default settings and let the installer complete its work. Once done, open a &lt;code&gt;Command Prompt&lt;/code&gt; (aka &lt;span class="caps"&gt;&lt;span class="caps"&gt;DOS&lt;/span&gt;&lt;/span&gt; Command Line) window by selecting the Start menu, then the Run&amp;#8230; menu item, and then typing &lt;code&gt;cmd&lt;/code&gt; and pressing return.&lt;/p&gt;
&lt;p&gt;You can check that Ruby is installed by typing the command:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; ruby -v
	ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
&lt;/pre&gt;
&lt;p&gt;You should seem similar responses. If you get an unrecognized command error, try closing your Command Prompt window and opening another one.&lt;/p&gt;
&lt;h3&gt;Ruby Gems Package Manager&lt;/h3&gt;
&lt;p&gt;You next need to install the latest version of &lt;code&gt;gem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Check the version that gets installed:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem -v
	0.9.4
&lt;/pre&gt;
&lt;p&gt;You need 1.0.1 or newer. If you have an older version, you can update with the command line: &lt;code&gt;gem update --system&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Installing a Subversion client&lt;/h3&gt;
&lt;p&gt;Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion command line client and you can use the &lt;a href="http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91"&gt;official Windows installers on subversion.tigris.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Download the latest &amp;#8220;Windows installer with the basic win32 binaries&amp;#8221; option on the site. Double click the setup program and select the default options.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_svn.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Once the installer is done, open a new Command Prompt window and check the installation:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; svn --version
	svn, version 1.4.6 (r28521)
	   compiled Dec 20 2007, 16:33:06
	...
&lt;/pre&gt;
&lt;h3&gt;Installing MySQL via the Offical MySQL Installer&lt;/h3&gt;
&lt;p&gt;You will be installing MySQL via the official &lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html#win32"&gt;Windows Essentials&lt;/a&gt; installer from MySQL.com. This installer handles all of the setup steps for you. After downloading the community edition (open source) Windows Essentials setup program, double click it to start:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_mysql_1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Select the default (&amp;#8220;Typical&amp;#8221;) settings and location and let the program install itself. After it completes, a few ads will be shown, then a final dialog allowing you to configure the MySQL server. Make sure the check-box is selected and press &amp;#8220;Finish&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_mysql_2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The &amp;#8220;MySQL Server Instance Configuration Wizard&amp;#8221; will run next. Choose the &amp;#8220;Detailed Configuration&amp;#8221; option and select all of the default choices. Doing so will configure the database to be running with settings best designed for a developer&amp;#8217;s computer. When you get to the dialog offering the &amp;#8220;Include Bin Directory in Windows &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt;&amp;#8221; option, we suggest you select it. If you don&amp;#8217;t choose this option, you will need to manually set up your path so the &amp;#8220;Command Prompt&amp;#8221; program has easy access to MySQL client programs.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_mysql_3.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You will also be presented with a dialog to set a root password. If you are going to be working locally and aren&amp;#8217;t worried about security, you can deselect &amp;#8220;Modify Security Settings&amp;#8221; and have a blank root password. We strongly suggest you set a password to be safe.&lt;/p&gt;
&lt;p&gt;You can confirm that MySQL is running by trying to fire it up in the Command Prompt program:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; mysql -p -u root
	Enter password: ****
	Welcome to the MySQL monitor.  Commands end with ; or \g.
	Your MySQL connection id is 1
	Server version: 5.0.51a-community-nt MySQL Community Edition (GPL)

	Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

	mysql&amp;amp;gt; exit
&lt;/pre&gt;
&lt;p&gt;When you reboot your computer, MySQL will start automatically in the future.&lt;/p&gt;
&lt;h3&gt;Gems&lt;/h3&gt;
&lt;p&gt;While the One-Click Ruby installer added some common Windows oriented gems for you, you still need the Ruby on Rails gems and the gems used in the LearningRails course. Install them with the command:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem install rails capistrano mongrel mongrel_cluster
&lt;/pre&gt;
&lt;p&gt;All installed gems (including Ruby on Rails and its dependencies, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.&lt;/p&gt;
&lt;p&gt;The MySQL adapter gem needs to be installed next.&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem install mysql
&lt;/pre&gt;
&lt;p&gt;Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.&lt;/p&gt;
&lt;h3&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; Terminal Program&lt;/h3&gt;
&lt;p&gt;In deployment environments where your production or other remote servers are running a Unix-derived operating system, you will want to log in to those machines using the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; protocol. A good Windows &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; terminal program is &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;PuTTY&lt;/a&gt;. Download the complete Windows installer and double click to let it run.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinxp_putty.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You can select all of the default options. Once the installer finishes, you are ready to login to your remote machines.&lt;/p&gt;
&lt;h3&gt;Installing a Git client&lt;/h3&gt;
&lt;p&gt;Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. The &lt;a href="http://code.google.com/p/msysgit/"&gt;Git on MSys&lt;/a&gt; project team has done a nice job of building the git tools and a simple installer for Windows.&lt;/p&gt;
&lt;p&gt;Download the latest installer (latest as of the last update of this article was &lt;a href="http://msysgit.googlecode.com/files/Git-1.5.6.1-preview20080701.exe"&gt;Git-1.5.6.1-preview20080701.exe&lt;/a&gt;) and double click the executable.&lt;/p&gt;
&lt;p&gt;During setup, you will be presented with a number of screens. Select the defaults until you get to the following two dialogs:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;&amp;#8220;Adjust your &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt; environment&amp;#8221;&lt;/strong&gt; dialog. Select the &lt;em&gt;&amp;#8220;Run Git from the Windows Command Prompt&amp;#8221;&lt;/em&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;&amp;#8220;Choosing the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; executable&amp;#8221;&lt;/strong&gt; dialog. Select &lt;em&gt;&amp;#8220;Use PLink&amp;#8221;&lt;/em&gt; since we just installed Putty.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The installer should complete, and you can optionally review the ReleaseNotes.rtf file.&lt;/p&gt;
&lt;p&gt;The installer command places the core git tools and the man page documentation (type &lt;code&gt;git help _commandname_&lt;/code&gt; for help) on your machine and updates the &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt; so you can use git from the Command Prompt. &lt;code&gt;ruby script\plugin install&lt;/code&gt; should find git and use it for installation of newer plugins.&lt;/p&gt;
&lt;p&gt;Note that if you have an older Rails project, you&amp;#8217;ll want to update to Rails 2.1 or newer to get the latest support for git. When you upgrade, update your project with the &lt;code&gt;rake rails:update&lt;/code&gt; command.&lt;/p&gt;
&lt;h3&gt;Code Editing Tools&lt;/h3&gt;
&lt;p&gt;While you can get by with using a plain text editor like Notepad you will have much higher productivity if you use a programming editor that is highly tuned to Ruby on Rails development. The One-Click Ruby installer automatically installed the SciTE programmer&amp;#8217;s editor. SciTE is ok for basic tasks with one or two files, but we recommend trying some of the other programs below.&lt;/p&gt;
&lt;p&gt;We use the commercial &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; programmer&amp;#8217;s editor for much of our day to day work on the Macintosh. TextMate is highly extensible through a collection of community supplied &amp;#8220;bundles&amp;#8221;. There is a Windows &amp;#8220;look-a-like/port&amp;#8221; called the &lt;a href="http://e-texteditor.com/"&gt;E Text Editor&lt;/a&gt; that looks promising and includes much of the functionality found on the Mac. Even better, it is supposed to be compatible with TextMate bundles, so as functionality improves for one platform, it should become available on the other. There is a trial version available if you want to test it out.&lt;/p&gt;
&lt;p&gt;There are a variety of good open source or free programmer editors available too. On the open source side you can find ports of vim and emacs, both of which have add-ons to create a full featured Ruby and Rails development tool set. &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; is a very extensible open source editor written in Java that has a decent Ruby programming plugin set.&lt;/p&gt;
&lt;p&gt;Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.&lt;/p&gt;
&lt;p&gt;If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; in our LearningRails courses, but you should check out the numerous &lt;a href="http://www.buildingwebapps.com/topic/26-integrated-development-environments-ides"&gt;other options listed at BuildingWebApps.com&lt;/a&gt;.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=RIcFcyWgCns:HpVZa7kNk0o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=RIcFcyWgCns:HpVZa7kNk0o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=RIcFcyWgCns:HpVZa7kNk0o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=RIcFcyWgCns:HpVZa7kNk0o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/RIcFcyWgCns" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6467-setting-up-rails-on-windows-xp</feedburner:origLink></entry>
  <entry>
    <title>Remote Linux Admin for Windows Users</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/JvSB6WomRok/6398-remote-linux-admin-for-windows-users" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6398-remote-linux-admin-for-windows-users</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>A lot of the remote server administration information on the web assumes that you're on either a Mac or a Linux box. This assumption can add challenges for Windows users, but there are tools available to make Windows do most everything a Linux system does.</summary>
    <content type="html">
&lt;p&gt;All the cool kids in the web world these days seem to be using Macs, which have hearts of Unix so are natural complements to Linux-based servers. Others are running Linux desktops. So a lot of the remote server administration information on the web assumes that you&amp;#8217;re on either a Mac or a Linux box.&lt;/p&gt;
&lt;p&gt;For historical reasons, however, I have a collection of Windows systems, and they&amp;#8217;re what I&amp;#8217;m comfortable with. I also have some things, like my collection of 60,000 photos managed in the Photoshop Elements Organizer, that aren&amp;#8217;t easily moved to a Mac, and I have lots of Windows applications that I own and am familiar with. So while I don&amp;#8217;t have any religious feelings about it (please, spare me the Mac evangelism), I&amp;#8217;m using Windows systems to remotely administer my web servers.&lt;/p&gt;
&lt;p&gt;This really isn&amp;#8217;t a problem, as there are ample tools available to make Windows do most everything a Linux system does, or a least everything you need to do to administer one remotely. But it does take a little more effort, at times, to track down the right tools and figure out how to apply them. If you&amp;#8217;re early in this process, this article may help. (If, on the other hand, you&amp;#8217;re a grey-beard Linux hacker or a Mac die-hard, you can stop reading now.)&lt;/p&gt;
&lt;p&gt;Although there are &lt;span class="caps"&gt;&lt;span class="caps"&gt;GUI&lt;/span&gt;&lt;/span&gt; interfaces for Linux, remote administration is done predominantly from the command line. And if you want to follow the well-greased paths for deploying Rails applications, you&amp;#8217;re going to be living in a command-line world. This is, of course, rather alien in the Windows environment.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s really two command-line environments you need to use: the Windows command shell,  for taking actions on your local machine, and a Linux shell, for interacting directly with your server. The Windows shell is essentially a grown-up version of the old &lt;span class="caps"&gt;&lt;span class="caps"&gt;DOS&lt;/span&gt;&lt;/span&gt; prompt. Linux shells come in a variety of versions, with &lt;span class="caps"&gt;&lt;span class="caps"&gt;BASH&lt;/span&gt;&lt;/span&gt; being the most common.&lt;/p&gt;
&lt;h1&gt;Enhancing the Windows Command Window&lt;/h1&gt;
&lt;p&gt;You need to use the Windows shell to control your local development environment, and with some extensions (to be described in a later post), you can use it for some tasks that involve your remote server as well.&lt;/p&gt;
&lt;p&gt;To open a Windows command shell, you can select Run from Start menu and then enter cmd and click OK. But there&amp;#8217;s a better way: Microsoft offers a free add-on that lets you open a command window by right-clicking on any folder and choosing a new option that the add-on installs, &amp;#8220;Open Command Window Here.&amp;#8221; Aside from being quicker than the Start &amp;gt; Run &amp;gt; cmd approach, it opens the command window with the current directory set to the folder upon which you right clicked. &lt;a href="http://download.microsoft.com/download/whistler/Install/2/WXP/EN-US/CmdHerePowertoySetup.exe"&gt;Download the command window PowerToy&lt;/a&gt;. It is entirely painless and will make your life just a little bit simpler.&lt;/p&gt;
&lt;p&gt;Now you should customize your command window settings, as the defaults are pathetic. The window has no menu, so it may not be immediately clear how one customizes it. The secret is to open any command window, right-click on the title bar, and choose Properties. Once in the properties dialog, here&amp;#8217;s some things you might want to change:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;In the Options tab, check the boxes to enable Quick Edit Mode and Insert Mode. This enables you to cut and paste text (you can&amp;#8217;t use ctrl-X and ctrl-V like you can in a &lt;span class="caps"&gt;&lt;span class="caps"&gt;GUI&lt;/span&gt;&lt;/span&gt; environment). To copy, select the text and then click the right mouse button. To paste, just click the right mouse button.&lt;/li&gt;
	&lt;li&gt;Also in the Options tab, change the Buffer Size to 999, and the Number of Buffers to 5. This gives you more memory for past commands. At any command prompt, press the up arrow repeatedly to move back through previous commands. This can save a lot of typing.&lt;/li&gt;
	&lt;li&gt;In the Layout tab, increase the Screen Buffer Height to 2500, so you&amp;#8217;ll have more text you can scroll back through after it scrolls off the top of the window. Increase the Screen Height to provide a window as tall as you&amp;#8217;d like; I prefer 75 for my 1200-pixel-high monitors.&lt;/li&gt;
	&lt;li&gt;In the Colors tab, change the text and background colors if you&amp;#8217;d like. White text on a black background is traditional and has a retro appeal, but I prefer black text on a white background.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you&amp;#8217;re done making changes, click OK, and then choose Save Properties for Future Windows in the dialog that appears. Now you&amp;#8217;ll have a much nicer command window to work with from now on.&lt;/p&gt;
&lt;h1&gt;Get Set up for &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Although you can use the Windows command prompt to act upon your remote server, the primary method used to access Linux systems remotely is &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; (Secure Shell). There&amp;#8217;s not an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; client built in to Windows, but good free clients are available. The most popular is PuTTY. &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;Download the PuTTY installer package&lt;/a&gt;. Choose the download labeled &amp;#8220;A Windows installer for everything except PuTTYtel&amp;#8221;, which will get you the complete set of PuTTY utilities, some of which you&amp;#8217;ll want later.&lt;/p&gt;
&lt;p&gt;Run PuTTY, and you&amp;#8217;ll see a deceptively simple window. There&amp;#8217;s actually lots of options here, which you can explore by clicking the categories on the left. But you can get started by using all the defaults and simply entering the name of your host (or its IP address) in the Host Name field and clicking Open. (To save yourself a little typing in the future, you can enter a name under Saved Sessions and click Save, and then the next time you can just double-click this name in the Saved Sessions list.)&lt;/p&gt;
&lt;p&gt;Assuming PuTTY is able to connect to your host, you&amp;#8217;ll then see another of those lovely white text on a black background windows (you can change these settings in the initial PuTTY dialog), with a &lt;strong&gt;Login:&lt;/strong&gt; prompt. At this prompt, enter the user name your host assigned you, and then you&amp;#8217;ll get a password prompt. Enter the correct password, and you&amp;#8217;ll be online talking to your server, with essentially all the control that a user sitting at the machine has. All data sent back and forth is securely encrypted, so no one will be able to sniff your network traffic and figure out how to get into your server (unlike &lt;span class="caps"&gt;&lt;span class="caps"&gt;FTP&lt;/span&gt;&lt;/span&gt;, in which not only your files but also your user name and password are sent in clear text).&lt;/p&gt;
&lt;p&gt;If you aren&amp;#8217;t able to connect to your server (even to the point of getting a Login prompt), then check the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Make sure your host has enabled &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; access. If you have a shared hosting account, it might not be offered, or you might have to ask for it.&lt;/li&gt;
	&lt;li&gt;Make sure you have the host name right. This should be simply the domain of your web site. If it is a new account and you haven&amp;#8217;t set the &lt;span class="caps"&gt;&lt;span class="caps"&gt;DNS&lt;/span&gt;&lt;/span&gt; yet, you can use the IP address.&lt;/li&gt;
	&lt;li&gt;If all else fails, check with your host to see if they&amp;#8217;ve moved &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; to a port other than the standard 22. Some companies are doing this to reduce brute-force attacks. You can enter any port number in the PuTTY dialog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If, on the other hand, you get the login prompt but it doesn&amp;#8217;t accept your user name or password, double-check that you have these exactly correct. For some hosts, you may need to use &amp;#8220;name@domain.com&amp;#8221; and not just &amp;#8220;name&amp;#8221; for your login name. Check the signup material you received when you opened the hosting account.&lt;/p&gt;
&lt;p&gt;Once you have these two command-line environments in place, you have the essential tools to both control your local development environment and to administer your server. Now you just need to know what to type into these windows :-).&lt;/p&gt;
&lt;h1&gt;For more information:&lt;/h1&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.jfitz.com/tips/ssh_for_windows.html"&gt;Excellent overview of &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; software for Windows&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true"&gt;Windows Command Shell Overview&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://technet2.microsoft.com/WindowsServer/en/library/552ed70a-208d-48c4-8da8-2e27b530eac71033.mspx?mfr=true"&gt;Complete (though badly presented) Windows Command Reference&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://commandwindows.com/command3.htm"&gt;A good third-party Windows command line reference&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.cygwin.com/"&gt;Cygwin is a Linux-like environment for Windows&amp;#8230;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=":http://technet.microsoft.com/en-us/interopmigration/bb380242.aspx"&gt;Windows Services for Unix&lt;/a&gt; contained an emulation environment and useful tools. (Deprecated but might be useful.)&lt;/li&gt;
&lt;/ul&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=JvSB6WomRok:chpr99A1aNY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=JvSB6WomRok:chpr99A1aNY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=JvSB6WomRok:chpr99A1aNY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=JvSB6WomRok:chpr99A1aNY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/JvSB6WomRok" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6398-remote-linux-admin-for-windows-users</feedburner:origLink></entry>
  <entry>
    <title>BarCamp Miami 2008</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/QeRMcCC6YjA/6431-barcamp-miami-2008" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6431-barcamp-miami-2008</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>BarCamp Miami was held February 28th, 2008, concurrent with the Future of Web Apps Miami conference (and shared the nice Carnival Performing Arts Center venue). Up until this point, I hadn't been to a BarCamp, though I have participated in other unconferences before.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width:350px; margin: 0 10px 5px 0'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/barcampmiami.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;BarCamp Miami was held February 28th, 2008, concurrent with the Future of Web Apps Miami conference (and shared the nice Carnival Performing Arts Center venue). Up until this point, I hadn&amp;#8217;t been to a &lt;a href="http://barcamp.org/"&gt;BarCamp&lt;/a&gt;, though I have participated in other &lt;a href="http://en.wikipedia.org/wiki/Unconference"&gt;unconferences&lt;/a&gt; before.&lt;/p&gt;
&lt;p&gt;BarCamps evolve on the spot with regard to the content, and Miami was an eclectic mix of talks volunteered from many of the 250 or so participants. As a BarCamp newbie, I, of course, had to give a talk. The process was simple enough: volunteer a topic, grab a room on the grid, and then lead that session. Attending talks was pretty much the same: check the grid, go to the talk, and participate in discussion.&lt;/p&gt;
&lt;p&gt;&lt;img src="/barcampagenda.jpg" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;Talks in Brief&lt;/h2&gt;
&lt;h3&gt;How Not to &lt;span class="caps"&gt;&lt;span class="caps"&gt;FAIL&lt;/span&gt;&lt;/span&gt; at Web Services&lt;/h3&gt;
&lt;p&gt;First stop was Gregg Pollack&amp;#8217;s &amp;#8220;How Not to &lt;span class="caps"&gt;&lt;span class="caps"&gt;FAIL&lt;/span&gt;&lt;/span&gt; at Web Services&amp;#8221;. Gregg (cohost with partner Jason Seifer from the great &lt;a href="http://railsenvy.com/"&gt;Rails Envy podcast&lt;/a&gt;) dove in to how to conceptualize and build web service APIs the RESTful way. Unfortunately, when it comes to RESTful design, the world has fractured. Some have grokked Roy Fielding&amp;#8217;s thesis from his doctoral dissertation and the subsequent implementation best practices in Ruby on Rails and other technologies. Others have interpreted RESTful APIs to simply mean using &lt;span class="caps"&gt;&lt;span class="caps"&gt;XML&lt;/span&gt;&lt;/span&gt;, or perhaps &lt;span class="caps"&gt;&lt;span class="caps"&gt;JSON&lt;/span&gt;&lt;/span&gt;, as a payload, and wacky URLs that spell out a full &lt;span class="caps"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/span&gt; call without regard to how &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; really works. In Gregg&amp;#8217;s assessment, the later will be a sure way to &lt;span class="caps"&gt;&lt;span class="caps"&gt;FAIL&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;Does Rails Need More Love?&lt;/h3&gt;
&lt;p&gt;I had snagged an early time slot, so I wandered over to my designated room to prep. My talk was entitled &lt;a href="http://www.flickr.com/photos/allanbranch/2298273557/"&gt;Does Rails Need More Love?&lt;/a&gt; and focused on the problems facing designers and developers just learning Rails 2. As readers of BuildingWebApps.com and our &lt;a href="http://blog.buildingwebapps.com/2008/2/24/the-pain-of-redefining-scaffold"&gt;blog&lt;/a&gt; have heard us say before, Rails 2 has fundamentally broken almost all documentation, books, tutorials, and other reference materials out there for new Ruby on Rails learners. I proceeded to explain this sad state of affairs, talk about what we are trying to do to help (BuildingWebApps.com as a commercial hub for resources, new articles under Creative Commons, free podcasts), and opened the floor to discussion of what people really need to help them learn.&lt;/p&gt;
&lt;p&gt;I received a lot of good feedback about our site, as well as thoughtful commentary on the different materials people would like to see more of to learn Ruby on Rails (and really, any other web technology). Some of the top contenders were tutorials that stay current, book efforts similar to Python&amp;#8217;s &lt;a href="http://www.djangobook.com/"&gt;Django Book&lt;/a&gt;, and more newbie-friendly forums.&lt;/p&gt;
&lt;h3&gt;Should Kids Surf the Web?&lt;/h3&gt;
&lt;p&gt;After my session, I walked in to &lt;a href="http://www.thinkjose.com/"&gt;Jose Castillo&amp;#8217;s&lt;/a&gt; talk about &amp;#8220;Should Kids Surf the Web?&amp;#8221;. This was interesting to me from two points of view: 1) as a parent of a couple of younger, computer-savvy kids, I&amp;#8217;m always curious as to the latest ideas around children and technology; and 2) some of my previous start-up companies focused on children&amp;#8217;s education and entertainment software, some of which was net related.&lt;/p&gt;
&lt;p&gt;Jose is a great speaker and he showcased a recent project called &lt;a href="http://www.gotrybe.com/"&gt;GoTrybe&lt;/a&gt;, which is a kid&amp;#8217;s goal-setting and physical-fitness-oriented social application that the state of Tennessee is helping to drive. The side discussion was interesting too, looking for ways to promote the positive aspects of Internet usage by kids and help fight fear-mongering and lack of knowledge (and common sense) among many who want to keep kids away from technology in general. No final solutions, alas!&lt;/p&gt;
&lt;h3&gt;Coworking: Because Working Alone &lt;span class="caps"&gt;&lt;span class="caps"&gt;SUCKS&lt;/span&gt;&lt;/span&gt;!&lt;/h3&gt;
&lt;p&gt;BuildingWebApps.com is a virtual company with respect to its physical offices. Since I spend a lot of time at my home office, it was with some interest I attended &lt;a href="http://blog.coworking.info/"&gt;Alex Hillman&amp;#8217;s&lt;/a&gt; talk &amp;#8220;Coworking: Because Working Alone &lt;span class="caps"&gt;&lt;span class="caps"&gt;SUCKS&lt;/span&gt;&lt;/span&gt;!&amp;#8221; talk.&lt;/p&gt;
&lt;p&gt;Coworking is where you have a shared office space, with one or more other people working there, although not necessarily for the same company/job/project. It is a mash-up of office space, cafe culture, and camaraderie. Alex gave a number of examples of &amp;#8220;how it works&amp;#8221; with respect to finding space, finding compatible coworkers, building trust, general bootstrapping, logistics, etc.&lt;/p&gt;
&lt;p&gt;It was refreshing to see the different approaches. I think the trick to kicking off a successful coworking space is having that critical mass of creative folks who &amp;#8220;get it.&amp;#8221; Living up in the Sierra Nevada foothills, I&amp;#8217;m hoping I can find an opportunity to try coworking someday.&lt;/p&gt;
&lt;h3&gt;Launch Your Company in 48 hours&lt;/h3&gt;
&lt;p&gt;OK, that wasn&amp;#8217;t the name of the talk, but the guys over at &lt;a href="http://tastyplanner.com/"&gt;Tasty Planner&lt;/a&gt; presented their company and product. Tasty Planner was conceived of and initially built as an entry in &lt;a href="http://railsrumble.com/"&gt;2007&amp;#8217;s Rails Rumble Contest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Rails Rumble is the Iron Man Triathlon of Ruby on Rails programming. Your team has 48 hours to build from scratch a compelling application.&lt;/p&gt;
&lt;p&gt;Tasty Planner is a menu creation, planning, shopping, and sharing application that seems pretty cool. The four team members discussed their approach and key take-aways. Most important, they:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;agreed to make decisions quickly,&lt;/li&gt;
	&lt;li&gt;had mostly clear areas of responsibility, and&lt;/li&gt;
	&lt;li&gt;consumed a lot of caffeine.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Things went so well that one team member took time to go to a concert too! This was a fun talk and we all got to check out the &lt;a href="http://flickr.com/photos/thinkjose/2299779801/"&gt;heavy weight prize&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;BarCamp Takeaways&lt;/h2&gt;
&lt;p&gt;BarCamp is all about networking. While the sessions were excellent, even better was the chance to mingle between sessions and in the hallways, making contacts and exchanging ideas. If you have a chance to attend a BarCamp (be sure to check the &lt;a href="http://barcamp.org/"&gt;official BarCamp wiki&lt;/a&gt;, they are literally being organized around the world), do try to give a talk. It is the fastest way to start meeting people.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/tags/barcampmiami/"&gt;Flickr Pictures from BarCamp Miami&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://barcamp.org/BarCampMiami"&gt;Official BarCamp Miami Page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.technorati.com/tag/barcampmiami08"&gt;Articles Revolving Around BarCamp Miami&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=QeRMcCC6YjA:LzDR70ry8rk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=QeRMcCC6YjA:LzDR70ry8rk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=QeRMcCC6YjA:LzDR70ry8rk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=QeRMcCC6YjA:LzDR70ry8rk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/QeRMcCC6YjA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6431-barcamp-miami-2008</feedburner:origLink></entry>
  <entry>
    <title>Setting up Rails on Windows Vista</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/blnL2ZbTRHQ/6491-setting-up-rails-on-windows-vista" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6491-setting-up-rails-on-windows-vista</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>This guide walks you through setup instructions for preparing a Windows Vista development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our LearningRails online course.</summary>
    <content type="html">
&lt;p&gt;This guide walks you through setup instructions for preparing a Windows Vista development machine to be used for general Ruby on Rails coding. This baseline setup is what we use for our &lt;a href="/course"&gt;LearningRails online course&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will end up with a development machine with the following baseline components:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Ruby and all basic Ruby utilities&lt;/li&gt;
	&lt;li&gt;Ruby Gems package manager&lt;/li&gt;
	&lt;li&gt;Subversion client&lt;/li&gt;
	&lt;li&gt;MySQL database client utilities and server&lt;/li&gt;
	&lt;li&gt;Gems for Ruby on Rails, Capistrano, Mongrel, Mongrel Cluster, and MySQL&lt;/li&gt;
	&lt;li&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; Terminal Program&lt;/li&gt;
	&lt;li&gt;Git client (&lt;span class="caps"&gt;&lt;span class="caps"&gt;UPDATED&lt;/span&gt;&lt;/span&gt;)&lt;/li&gt;
	&lt;li&gt;Programmer&amp;#8217;s editor or &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: In the command sequences we illustrate here, command line prompts are shown as &lt;code&gt;C:\&amp;amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;This guide assumes you have a Windows computer running the current Windows Vista operating system with up-to-date service patches applied (SP1 or higher). It also assumes you have not set up alternate Ruby on Rails tools prior to running through this guide. If you have, then small adjustments may be required as you walk through the following instructions.&lt;/p&gt;
&lt;p&gt;You will need to have access to an Internet connection to complete various download steps.&lt;/p&gt;
&lt;p&gt;You will need to have administrator access to your computer to complete this guide. Some of the Windows installers may ask you for your password. With most of the installer programs described below, Windows Vista will present the famous User Account Control (&lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt;) dialog asking whether an unidentified program should be permitted to have access to your computer.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_uac.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You should select the &amp;#8220;Allow&amp;#8221; option which will let the specific installer program continue. In the specific case of MySQL, the MySQL installation process is not compatible with &lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt;. We will walk you through temporarily turning &lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt; off so you can install MySQL.&lt;/p&gt;
&lt;h2&gt;The Recipe&lt;/h2&gt;
&lt;p&gt;Follow this recipe in sequence. If you have previously installed a particular component, you can usually skip the associated step.&lt;/p&gt;
&lt;h3&gt;Ruby and Ruby Utilities (irb, ri, rdoc)&lt;/h3&gt;
&lt;p&gt;The &lt;a href="http://rubyforge.org/projects/rubyinstaller/"&gt;One-Click Ruby Installer&lt;/a&gt; does a lot of work for you by installing Ruby, Ruby Gems Package Manager, Rake, all of the other standard Ruby tools, and even the open source SciTE programmer&amp;#8217;s editor. Additionally, the installer configures the command line interface path information, so the Ruby tools are ready to use in the Command Prompt program.&lt;/p&gt;
&lt;p&gt;Download the latest installer (1.8.6 r26 as of this writing) and double click on it to get started.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_1click.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Select all of the default settings and let the installer complete its work. Once done, open a &lt;code&gt;Command Prompt&lt;/code&gt; (aka &lt;span class="caps"&gt;&lt;span class="caps"&gt;DOS&lt;/span&gt;&lt;/span&gt; Command Line) window by selecting the Start menu, then enter &lt;code&gt;cmd&lt;/code&gt; into the Start Search text box and pressing return.&lt;/p&gt;
&lt;p&gt;You can check that Ruby is installed by typing the command:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; ruby -v
	ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
&lt;/pre&gt;
&lt;p&gt;You should seem similar responses. If you get an unrecognized command error, try closing your Command Prompt window and opening another one.&lt;/p&gt;
&lt;h3&gt;Ruby Gems Package Manager&lt;/h3&gt;
&lt;p&gt;You next need to install the latest version of &lt;code&gt;gem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Check the version that gets installed:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem -v
	0.9.4
&lt;/pre&gt;
&lt;p&gt;You need 1.0.1 or newer. If you have an older version, you can update with the command line: &lt;code&gt;gem update --system&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Installing a Subversion client&lt;/h3&gt;
&lt;p&gt;Subversion will be used to access your source code repository during development and deployments. You will need a current version of the Subversion command line client and you can use the &lt;a href="http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91"&gt;official Windows installers on subversion.tigris.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Download the latest &amp;#8220;Windows installer with the basic win32 binaries&amp;#8221; option on the site. Double click the setup program and select the default options.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_svn.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Once the installer is done, open a new Command Prompt window and check the installation:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; svn --version
	svn, version 1.4.6 (r28521)
	   compiled Dec 20 2007, 16:33:06
	...
&lt;/pre&gt;
&lt;h3&gt;Installing MySQL via the Offical MySQL Installer&lt;/h3&gt;
&lt;p&gt;You will be installing MySQL via the official &lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html#win32"&gt;Windows Essentials&lt;/a&gt; installer from MySQL.com. This installer handles all of the setup steps for you.&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;NOTE&lt;/span&gt;&lt;/span&gt;: As of this writing, MySQL 5.0.51a and 5.1.23rc have bugs that prevent simple installation onto Vista. A &lt;a href="http://forums.mysql.com/read.php?11,195569,195569"&gt;workaround recipe is available&lt;/a&gt; but it is complicated. We recommend using a &lt;a href="http://downloads.mysql.com/archives.php?p=mysql-5.0&amp;amp;v=5.0.45"&gt;slightly older version, MySQL 5.0.45&lt;/a&gt;, as it doesn&amp;#8217;t have the current installation bugs. We&amp;#8217;ll update these instructions once fixes to the current MySQL line are available.&lt;/p&gt;
&lt;p&gt;Unfortunately, the MySQL installer and Windows Vista User Account Control (&lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt;) conflict with one-another. You will have to temporarily turn &lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt; off.&lt;/p&gt;
&lt;p&gt;First, go to the &lt;code&gt;Start Menu&lt;/code&gt;, select &lt;code&gt;Control Panel&lt;/code&gt;, and then click on &lt;code&gt;User Accounts and Family Safety&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_uac1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Click on the &lt;code&gt;User Accounts&lt;/code&gt; link to open your account&amp;#8217;s setting dialog:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_uac2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Click on the &lt;code&gt;Turn User Account Control on or off&lt;/code&gt; link. Assuming that User Account Control is still on, Windows Vista will ask for permission to continue with turning User Account Control off. Nice and circular, yes? Now you can actually turn &lt;span class="caps"&gt;&lt;span class="caps"&gt;UAC&lt;/span&gt;&lt;/span&gt; off. Unselect the checkbox and press OK.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_uac3.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You will be prompted to restart your computer. Go ahead and do so now.&lt;/p&gt;
&lt;p&gt;One other change you will need to make is to open your Windows Vista Firewall to permit MySQL connections to the MySQL server port (3306). To do so, open &lt;code&gt;Control Panel&lt;/code&gt; again, and select the &lt;code&gt;Allow a program through Windows Firewall&lt;/code&gt; option of the Security group.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_fw1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Press the &lt;code&gt;Add port...&lt;/code&gt; button, and enter &lt;code&gt;MySQL&lt;/code&gt; in the &amp;#8220;Name:&amp;#8221; field and &lt;code&gt;3306&lt;/code&gt; in the &amp;#8220;Port number:&amp;#8221; field. Leave the protocol as &amp;#8220;&lt;span class="caps"&gt;&lt;span class="caps"&gt;TCP&lt;/span&gt;&lt;/span&gt;&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_fw2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Press OK on the Windows Firewall Settings dialog box and close the Control Panel.&lt;/p&gt;
&lt;p&gt;Finally, you can get on with installing MySQL. Double-click the community edition (open source) Windows Essentials MySQL setup program to get started:&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_mysql_1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Select the default (&amp;#8220;Typical&amp;#8221;) settings and location and let the program install itself. After it completes, a few ads will be shown, then a final dialog allowing you to configure the MySQL server. Make sure the check-box is selected and press &amp;#8220;Finish&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_mysql_2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The &amp;#8220;MySQL Server Instance Configuration Wizard&amp;#8221; will run next. Choose the &amp;#8220;Detailed Configuration&amp;#8221; option and select all of the default choices. Doing so will configure the database to be running with settings best designed for a developer&amp;#8217;s computer. When you get to the dialog offering the &amp;#8220;Include Bin Directory in Windows &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt;&amp;#8221; option, we suggest you select it. If you don&amp;#8217;t choose this option, you will need to manually set up your path so the &amp;#8220;Command Prompt&amp;#8221; program has easy access to MySQL client programs.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_mysql_3.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You will also be presented with a dialog to set a root password. If you are going to be working locally and aren&amp;#8217;t worried about security, you can deselect &amp;#8220;Modify Security Settings&amp;#8221; and have a blank root password. We strongly suggest you set a password to be safe.&lt;/p&gt;
&lt;p&gt;You can confirm that MySQL is running by trying to fire it up in the Command Prompt program:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; mysql -p -u root
	Enter password: ****
	Welcome to the MySQL monitor.  Commands end with ; or \g.
	Your MySQL connection id is 1
	Server version: 5.0.45-community-nt MySQL Community Edition (GPL)

	Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

	mysql&amp;amp;gt; exit
&lt;/pre&gt;
&lt;p&gt;When you reboot your computer, MySQL will start automatically in the future.&lt;/p&gt;
&lt;p&gt;Once you have confirmed MySQL is working, you can also reverse the steps above for re-enabling User Account Control.&lt;/p&gt;
&lt;h3&gt;Gems&lt;/h3&gt;
&lt;p&gt;While the One-Click Ruby installer added some common Windows oriented gems for you, you still need the Ruby on Rails gems and the gems used in the LearningRails course. Install them with the command:&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem install rails capistrano mongrel mongrel_cluster
&lt;/pre&gt;
&lt;p&gt;All installed gems (including Ruby on Rails and its dependencies, Capistrano, Mongrel, and Mongrel_Cluster) will get installed at their latest versions.&lt;/p&gt;
&lt;p&gt;The MySQL adapter gem needs to be installed next.&lt;/p&gt;
&lt;pre&gt;
	C:\&amp;amp;gt; gem install mysql
&lt;/pre&gt;
&lt;p&gt;Once the command completes, you should be all set with the baseline gems you will need for the LearningRails courses.&lt;/p&gt;
&lt;h3&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; Terminal Program&lt;/h3&gt;
&lt;p&gt;In deployment environments where your production or other remote servers are running a Unix-derived operating system, you will want to log in to those machines using the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; protocol. A good Windows &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; terminal program is &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;PuTTY&lt;/a&gt;. Download the complete Windows installer and double click to let it run.&lt;/p&gt;
&lt;p&gt;&lt;img src="/installwinvista_putty.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You can select all of the default options. Once the installer finishes, you are good to login to your remote machines.&lt;/p&gt;
&lt;h3&gt;Installing a Git client&lt;/h3&gt;
&lt;p&gt;Git is all the rage in the Rails world now and has pretty much replaced Subversion as the version control system of choice. That said, both are in common use. The &lt;a href="http://code.google.com/p/msysgit/"&gt;Git on MSys&lt;/a&gt; project team has done a nice job of building the git tools and a simple installer for Windows.&lt;/p&gt;
&lt;p&gt;Download the latest installer (latest as of the last update of this article was &lt;a href="http://msysgit.googlecode.com/files/Git-1.5.6.1-preview20080701.exe"&gt;Git-1.5.6.1-preview20080701.exe&lt;/a&gt;) and double click the executable.&lt;/p&gt;
&lt;p&gt;During setup, you will be presented with a number of screens. Select the defaults until you get to the following two dialogs:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;&amp;#8220;Adjust your &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt; environment&amp;#8221;&lt;/strong&gt; dialog. Select the &lt;em&gt;&amp;#8220;Run Git from the Windows Command Prompt&amp;#8221;&lt;/em&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;&amp;#8220;Choosing the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; executable&amp;#8221;&lt;/strong&gt; dialog. Select &lt;em&gt;&amp;#8220;Use PLink&amp;#8221;&lt;/em&gt; since we just installed Putty.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The installer should complete, and you can optionally review the ReleaseNotes.rtf file.&lt;/p&gt;
&lt;p&gt;The installer command places the core git tools and the man page documentation (type &lt;code&gt;git help _commandname_&lt;/code&gt; for help) on your machine and updates the &lt;span class="caps"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt; so you can use git from the Command Prompt. &lt;code&gt;ruby script\plugin install&lt;/code&gt; should find git and use it for installation of newer plugins.&lt;/p&gt;
&lt;p&gt;Note that if you have an older Rails project, you&amp;#8217;ll want to update to Rails 2.1 or newer to get the latest support for git. When you upgrade, update your project with the &lt;code&gt;rake rails:update&lt;/code&gt; command.&lt;/p&gt;
&lt;h3&gt;Code Editing Tools&lt;/h3&gt;
&lt;p&gt;While you can get by with using a plain text editor like Notepad you will have much high productivity if you use a programming editor that is highly tuned to Ruby on Rails development. The One-Click Ruby installer automatically installed the SciTE programmer&amp;#8217;s editor. SciTE is ok for basic tasks with one or two files, but we recommend trying some of the other programs below.&lt;/p&gt;
&lt;p&gt;We use the commercial &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; programmer&amp;#8217;s editor for much of our day to day work on the Macintosh. TextMate is highly extensible through a collection of community supplied &amp;#8220;bundles&amp;#8221;. There is a Windows &amp;#8220;look-a-like/port&amp;#8221; called the &lt;a href="http://e-texteditor.com/"&gt;E Text Editor&lt;/a&gt; that looks promising and includes much of the functionality found on the Mac. Even better, it is supposed to be compatible with TextMate bundles, so as functionality improves for one platform, it should become available on the other. Worth trying the trial at the least.&lt;/p&gt;
&lt;p&gt;There are a variety of good open source or free programmer editors available too. On the open source side you can find ports of vim and emacs, both of which have add-ons to create a full featured Ruby and Rails development tool set. &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; is a very extensible open source editor written in Java that has a decent Ruby programming plugin set.&lt;/p&gt;
&lt;p&gt;Whatever editor you choose, be certain that it provides easy navigation among a large number of open files. Working with Rails applications generally involves dealing with a lot of small files, and that process needs to be efficient.&lt;/p&gt;
&lt;p&gt;If you prefer an all-in-one tool, you should look at one of several integrated development environments that exist for Ruby. We use &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; in our LearningRails courses, but you should check out the numerous &lt;a href="http://www.buildingwebapps.com/topic/26-integrated-development-environments-ides"&gt;other options listed at BuildingWebApps.com&lt;/a&gt;.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=blnL2ZbTRHQ:p6fgv-HgLPw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=blnL2ZbTRHQ:p6fgv-HgLPw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=blnL2ZbTRHQ:p6fgv-HgLPw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=blnL2ZbTRHQ:p6fgv-HgLPw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/blnL2ZbTRHQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6491-setting-up-rails-on-windows-vista</feedburner:origLink></entry>
  <entry>
    <title>Seed Conference: The Creative Business Life</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/AUEmtKtibwk/6414-seed-conference-the-creative-business-life" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6414-seed-conference-the-creative-business-life</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>The one-day Seed Conference was for the most part, a series of personal essays by three unusually creative folks: Jason Fried of 37signals, Jim Coudal of Coudal Partners, and Carlos Segura of Segura Inc, t26, and a variety of other ventures. The conference was about design, web applications, and business, but its real focus was on creating a life and a business that you enjoy by following your creative inspirations.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width:350px; margin: 0 10px 5px 0'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/seed-1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The one-day Seed Conference was an event unlike any of the many conferences I&amp;#8217;ve attended over the past few decades. It was, for the most part, a series of personal essays by three unusually creative folks: Jason Fried of &lt;a href="http://37signals.com"&gt;37signals&lt;/a&gt;, Jim Coudal of &lt;a href="http://coudal.com"&gt;Coudal Partners&lt;/a&gt;, and Carlos Segura of &lt;a href="http://segura-inc.com"&gt;Segura Inc&lt;/a&gt; and a variety of other ventures. All are based in Chicago, where the event was held.&lt;/p&gt;
&lt;p&gt;&lt;img src="/segura_fried_coudal-1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p style="font-size:11px; margin-top:-12px;"&gt;Carlos Segura, Jason Fried, and Jim Coudal&lt;/p&gt;
&lt;p&gt;The program consisted of each of these three people speaking for an hour or two, followed by a panel discussion. It&amp;#8217;s hard to put a label on this event, which drew its attendees almost solely by the reputations of the speakers. The event was sold-out and filled the auditorium at the Illinois Institute of Technology to its capacity of 128 attendees.&lt;/p&gt;
&lt;p&gt;The conference was about design, web applications, and business, but its real focus was on creating a life and a business that you enjoy by following your creative inspirations. For anyone working in a large company, it was a persuasive, though indirect, call to strike out on your own (one that we heeded some time ago). For designers doing freelance work or running agencies, it was a rallying cry for creating your own products, rather than spending all your time applying your skills on behalf of others. And for everyone, it was an impassioned pitch for following your instincts, creating the best products you can, and having a great time doing it.&lt;/p&gt;
&lt;h2&gt;Carlos Segura: Art, Type, and Inspiration&lt;/h2&gt;
&lt;p&gt;Carlos worked as an art director for a string of large ad agencies before striking out on his own in 1991. He now runs multiple ventures, including the Segura Inc. agency, &lt;a href="http://t26.com"&gt;t26 type foundry&lt;/a&gt;, &lt;a href="http://5inch.com"&gt;5inch&lt;/a&gt; (silk-screened blank DVDs), and &lt;a href="http://cartype.com"&gt;Cartype&lt;/a&gt; (more than you can imagine about car emblems and logos).&lt;/p&gt;
&lt;p&gt;Carlos showed examples of amazing, multifaceted campaigns he created for Corbis and RockShox. Check out the &lt;a href="http://segura-inc.com/clients.php"&gt;client list on the Segura Inc. site&lt;/a&gt; for links to a variety of their work.&lt;/p&gt;
&lt;p&gt;Carlos created the &lt;a href="http://t26.com"&gt;t26 type foundry&lt;/a&gt; in 1994 out of frustration with the fonts available and the hassles with using it. By applying his own branding and marketing skills, on top of enlightened policies (t26 is the only type supplier that allows designers to legally provide fonts to service bureaus) and great new typefaces, he&amp;#8217;s built t26 into one of the largest independent type foundries.&lt;/p&gt;
&lt;h2&gt;Jason Fried: The 37signals Way&lt;/h2&gt;
&lt;p&gt;Jason Fried , the founder of &lt;a href="http://37signals.com"&gt;37signals&lt;/a&gt;, needs no introduction here, but perhaps the history of 37signals is not as well known. Jason began as a freelance designer and didn&amp;#8217;t really form a company until he had freelanced for three years and got the job to design GettyOne, for which he needed another designer. 37signals, founded in 1999, still has only 10 employees, most of whom work primarily from home. For such a small company, it has had a big impact.&lt;/p&gt;
&lt;p&gt;37signals became a product company with the launch of &lt;a href="http://basecamphq.com"&gt;Basecamp&lt;/a&gt;, from which Ruby on Rails was extracted. Basecamp was initially built as an internal tool, and then turned into a product. Their initial goal was $5K per month in revenue, which they exceeded within six weeks of launch. A year later, 37signals dropped all client work.&lt;/p&gt;
&lt;p&gt;Jason remains focused on user experience, while David Heinemeier Hansson, the co-owner of 37signals and original author of Rails, leads the development side of the business.&lt;/p&gt;
&lt;p&gt;Jason&amp;#8217;s talk was, for the most part, his well-honed &amp;#8220;Getting Real&amp;#8221; pitch. If you haven&amp;#8217;t already read the &lt;a href="http://gettingreal.37signals.com"&gt;Getting Real book&lt;/a&gt; and you&amp;#8217;ve made it this far into this article, it should be next on your list.&lt;/p&gt;
&lt;h2&gt;Just Wing It&lt;/h2&gt;
&lt;p&gt;Jason is a vocal advocate for doing away with most planning and just diving in and building products. He argues that plans never end up being what happens anyway, and that you&amp;#8217;re better off focusing your time on activities that lead directly to something you can put in front of customers. He takes an approach that is akin to Agile methods in the software development world, but applied to building businesses and doing design &amp;#8212; and taken, perhaps, to an extreme. He calls for us to &amp;#8220;embrace the unknown&amp;#8221; and &amp;#8220;just wing it&amp;#8221; since &amp;#8220;you don&amp;#8217;t know what you&amp;#8217;re doing anyway until you&amp;#8217;re doing it.&amp;#8221;&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a fascinating discussion to be had over the counterpoint that planning can provide a lot of value, but that didn&amp;#8217;t happen at this event, and it will have to wait for a future article to appear here.&lt;/p&gt;
&lt;p&gt;Another key point was that all too often there are too many cooks (too many participants in a project) and too few chefs: leaders who freely share their knowledge, as in cookbooks, in cooking shows, and so forth, and thereby build powerful personal brands while spreading their knowledge. Jason pointed out that Getting Real is the 37signals cookbook and asks, &amp;#8220;What&amp;#8217;s your cookbook?&amp;#8221; (This site is growing into ours.)&lt;/p&gt;
&lt;p&gt;Jason advocates for small teams and an easy-going approach. 37signals gives everyone Fridays off during the summer months, and Jason says just as much work gets done. He recommends hiring &amp;#8220;managers of one&amp;#8221; &amp;#8212; in other words, people who are self-managing.&lt;/p&gt;
&lt;p&gt;As for work style, Jason spoke out against the pervasive open workplace with its focus on nearly constant communication. &amp;#8220;A lot of people think interruption is collaboration,&amp;#8221; he commented.&lt;/p&gt;
&lt;p&gt;Financials remain one topic that Jason won&amp;#8217;t discuss, but he did say that Basecamp is the company&amp;#8217;s most profitable product, and Campfire its least-profitable.&lt;/p&gt;
&lt;p&gt;Some other tidbits:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;They do all their prototyping in &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; and &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt;, and don&amp;#8217;t use Photoshop for mock-ups.&lt;/li&gt;
	&lt;li&gt;They don&amp;#8217;t actively market the company, other than by blogging and speaking.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://highrisehq.com"&gt;Highrise&lt;/a&gt; came from an internal need to track journalists they were talking with.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Jim Coudal: Business Serendipity&lt;/h2&gt;
&lt;p&gt;Like Carlos Segura, Jim Coudal runs a creative agency (&lt;a href="http://coudal.com"&gt;Coudal Partners&lt;/a&gt;) and a host of spinoff products and businesses, including &lt;a href="http://coudal.com/deck/"&gt;The Deck&lt;/a&gt; (ad network), &lt;a href="http://www.theshowlive.com/"&gt;The Show&lt;/a&gt; (concert recordings), and &lt;a href="http://www.jewelboxing.com/"&gt;Jewelboxing&lt;/a&gt; (nice jewel boxes for CDs and DVDs). These sites are worth spending some time on just for inspiration, even if you aren&amp;#8217;t interested in the products.&lt;/p&gt;
&lt;p&gt;The site &lt;a href="http://coudal.com"&gt;Coudal&lt;/a&gt; has so much content on it that a note at the bottom proclaims, &amp;#8220;We actually do stuff other than update this site,&amp;#8221; with a link to the &amp;#8220;About Us&amp;#8221; page.&lt;/p&gt;
&lt;p&gt;Jim described how he moved away from client work, as an example of serendipity and following opportunities that present themselves. After years of doing design, web development, and filmmaking on behalf of clients, Coudal began developing short films and other projects just to show off the firm&amp;#8217;s talents. When a British TV production company expressed interest in turning one of these films into a series, Jim thought that was going to be their path away from client work. When sending out a sample &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;, Jim went looking for better packaging for the &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The TV show never happened, but &lt;a href="http://jewelboxing.com"&gt;Jewelboxing&lt;/a&gt; was born. Check it out if you need cool CD or &lt;span class="caps"&gt;&lt;span class="caps"&gt;DVD&lt;/span&gt;&lt;/span&gt; packaging.&lt;/p&gt;
&lt;p&gt;Triggered by an opportunity to produce CDs of live concert recordings for sale to concert-goers, Jim founded &lt;a href="http://theshowlive.com"&gt;The Show&lt;/a&gt;, in partnership with a Jewelboxing customer.&lt;/p&gt;
&lt;p&gt;Jim points out that enthusiasm for new ideas is typically highest early on, so by pursuing a series of projects you can stay higher on the enthusiasm curve.&lt;/p&gt;
&lt;p&gt;Like Jason, Jim argues against the need for things such as business plans. He described his goal as being to &amp;#8220;find a way to screw around at work all day and get paid for it,&amp;#8221; and it sounds as though he has accomplished just that!&lt;/p&gt;
&lt;h2&gt;Ready to Go?&lt;/h2&gt;
&lt;p&gt;Was it worth spending a day at? Absolutely. If I hadn&amp;#8217;t already read and absorbed Getting Real, it would have been even more so. Whether it was worth a San Francisco to Chicago trip, complete with a four-hour flight delay and waiting outside for a cab in snowy, 15-degree weather, is a tougher call, but I&amp;#8217;m glad I went. A two-day conference would have made much better use of all the travel time, though.&lt;/p&gt;
&lt;p&gt;Future Seed conferences haven&amp;#8217;t been scheduled, but given the sell-out crowd and how much the presenters seemed to enjoy themselves, it seems likely. Visit &lt;a href="http://seedconference.com"&gt;seedconference.com&lt;/a&gt; if you want to join the notification list for any announcements.&lt;/p&gt;
&lt;h2&gt;Other articles about the Seed Conference:&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;Mike Rohde&amp;#8217;s &lt;a href="http://www.flickr.com/photos/rohdesign/sets/72157602795582286/"&gt;sketchtoons&lt;/a&gt; conference notes&lt;/li&gt;
	&lt;li&gt;Mike&amp;#8217;s &lt;a href="http://www.rohdesign.com/weblog/archives/002389.html"&gt;blog post&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://giantrobots.thoughtbot.com/2008/1/22/the-seed-conference-in-chicago"&gt;thoughtbot&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.jess3.com/blog/2008/01/chicago-seed-conference-moto.html"&gt;jess3&lt;/a&gt; (with great pictures)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://flickr.com/search/?q=seed+conference"&gt;Flickr photos&lt;/a&gt; from the conference&lt;/li&gt;
&lt;p&gt;&lt;/ul&gt;&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=AUEmtKtibwk:4mSpmvCZ2Oc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=AUEmtKtibwk:4mSpmvCZ2Oc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=AUEmtKtibwk:4mSpmvCZ2Oc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=AUEmtKtibwk:4mSpmvCZ2Oc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/AUEmtKtibwk" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6414-seed-conference-the-creative-business-life</feedburner:origLink></entry>
  <entry>
    <title>Future of Web Apps Miami 2008</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/xoCWQ3HSJ9E/6432-future-of-web-apps-miami-2008" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6432-future-of-web-apps-miami-2008</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>Carsonified's Future of Web Apps, Miami, was held February 29th, 2008 at the Miami Carnival Performing Arts Center. FOWA brings together a who's who of Web 2.0 technorati to tackle general themes of interest revolving around where the Web is going. Getting inside thoughts from many of those who have made Web 2.0 successful is interesting, but even better is the discussion that goes on outside of the talks in the hall-ways.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width:400px; margin: 0 10px 5px 0'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/fowamiami.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Carsonified&amp;#8217;s &lt;em&gt;Future of Web Apps&lt;/em&gt;, Miami, was held February 29th, 2008 at the Miami Carnival Performing Arts Center (actually, there were tutorials the day before, and a beach party the following day, but I missed those events).&lt;/p&gt;
&lt;p&gt;Future of Web Apps, or &lt;span class="caps"&gt;&lt;span class="caps"&gt;FOWA&lt;/span&gt;&lt;/span&gt; for short, has been held before in London and San Francisco, and this was the first time it was held on the East Coast. &lt;span class="caps"&gt;&lt;span class="caps"&gt;FOWA&lt;/span&gt;&lt;/span&gt; brings together a who&amp;#8217;s who of Web 2.0 technorati to tackle general themes of interest revolving around where the Web is going. Ryan Carson, chief of Carsonified, lays out those themes and his guests tackle them in a series of talks. Getting inside thoughts from many of those who have made Web 2.0 successful is interesting, but even better is the discussion that goes on outside of the talks in the hall-ways. I found these to be inspiring and reaffirming of many of the practices, ideas, and goals we have with &lt;a href="http://buildingwebapps.com/"&gt;BuildingWebApps.com&lt;/a&gt; and beyond.&lt;/p&gt;
&lt;p&gt;In Miami, Carson&amp;#8217;s big themes were Iteration, Speed, and Openness. In many ways, the talks boiled these themes down to the sound byte of &amp;#8220;get something out there quickly, small and simple, wash, rinse, repeat (and throw in an &lt;span class="caps"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/span&gt; to &amp;#8216;set the data free&amp;#8217;)&amp;#8221;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll try to capture some highlights. From a developer point of view, the sessions were generally, well, general, so those looking for deep technical insight probably didn&amp;#8217;t find it in the single session track. From a &lt;em&gt;&amp;#8220;meet some of Web 2.0&amp;#8217;s current active drivers&amp;#8221;&lt;/em&gt; viewpoint, it was a good place to mingle.&lt;/p&gt;
&lt;h2&gt;Kathy Sierra: Creating Passionate Users&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://headrush.typepad.com/"&gt;Kathy Sierra&lt;/a&gt;, the keynote speaker, I recalled from her days in the game development world. She addressed the general question &amp;#8220;Why are we here?&amp;#8221; (meaning, &amp;#8220;we&amp;#8221; the audience). She proceeded to tackle a variety areas that should concern the audience in &amp;#8220;the future,&amp;#8221; all centering around the idea that what &amp;#8220;we&amp;#8221; should be doing is creating passionate users (of our products indirectly, most specifically of what users can do with our products, and what they can do with one-another). Ultimately, her point was that we should facilitate users getting together offline as well as on, and use our understanding of &amp;#8220;meet&amp;#8221;-space (my pun intended) to key in on important behavioral motivators.&lt;/p&gt;
&lt;p&gt;Sierra is a strong advocate of enabling users to &amp;#8220;kick ass&amp;#8221;, and touched on how to create &amp;#8220;hi-rez&amp;#8221; user experiences that get people quickly above the &amp;#8220;suck threshold&amp;#8221; and nearing the &amp;#8220;passion threshold&amp;#8221;. She reminded the audience that it isn&amp;#8217;t about the tools we create, but how the tools are used. Driving toward a &amp;#8220;telepathy-driven design&amp;#8221; mentality, in which the user experience becomes one of &amp;#8220;it&amp;#8217;s as if the app could read my mind&amp;#8221; is one goal.&lt;/p&gt;
&lt;p&gt;Overall, Sierra&amp;#8217;s talk was inspirational in keeping focused on the user, and keeping the user engaged, happy, and successful.&lt;/p&gt;
&lt;h2&gt;Matt Mullenweg: The Architecture of WordPress&lt;br /&gt;
 &lt;br /&gt;
Matt Mullenweg of &lt;a href="http://automattic.com/"&gt;Automattic&lt;/a&gt; (makers of &lt;a href="http://wordpress.com/"&gt;WordPress&lt;/a&gt;, &lt;a href="http://akismet.com/"&gt;Akismet&lt;/a&gt;, and more) highlighted his thoughts on scaling from multiple angles (platforms, business, community, and teams). This was a wide ranging talk, of which there were a few technical tidbits.&lt;/h2&gt;
&lt;p&gt;WordPress has continued to see high growth over the last six months, but amazingly operates on a relatively small numbers of servers. Mullenweg broke down one WordPress configuration as:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Two load-balancing machines, running the &lt;a href="http://www.apsis.ch/pound/"&gt;Pound&lt;/a&gt; load balancer, &lt;a href="http://www.backhand.org/wackamole/"&gt;Whackamole&lt;/a&gt; virtual IP manager, and &lt;a href="http://www.spread.org/"&gt;Spread&lt;/a&gt; messaging toolkit&lt;/li&gt;
	&lt;li&gt;Two hefty database servers running MySQL&lt;/li&gt;
	&lt;li&gt;Three web servers using a well-configured Apache setup&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;WordPress makes heavy use of its &lt;a href="http://2007.wordcamp.org/schedule/hyperdb-and-performance"&gt;hyperdb&lt;/a&gt; technology, puts everything into Subversion that does onto a server (all configuration and OS files), keeps things stateless, and uses a lot of &lt;a href="http://www.danga.com/memcached/"&gt;memcached&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mullenweg touched on scaling community and talks more about it &lt;a href="http://ma.tt/about/"&gt;on his blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With regards to scaling the business, he indicated that their attempts to have subscription levels didn&amp;#8217;t work so well, particularly since most of their growth was on the side of readers, not bloggers. They ended up going with a specialized advertising model that only shows ads to specific users when visiting permanent pages, or if the user only occasionally views the site. Interestingly, in a show of favoritism to FireFox users, they never show ads to users of FF.&lt;/p&gt;
&lt;p&gt;Mullenweg finished with some tips of how he is scaling the team and the five things he looks for when hiring: 1) passion for the space; 2) personality fit; 3) ability to learn (curiosity);  4) familiarity with technologies; and 5) taste.&lt;/p&gt;
&lt;h2&gt;Tantek Celik, Brian Oberkirch, and Joseph Smarr: The Future of Social Networks&lt;/h2&gt;
&lt;p&gt;Celik, Oberkirch, and Smarr gave a set of interconnected talks around some of the core building blocks for the next wave of social applications. In the large, these were &lt;a href="http://cyber.law.harvard.edu/rss/rss.html"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;RSS&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://creativecommons.org/"&gt;Creative Commons&lt;/a&gt; licensed content, &lt;a href="http://wiki.openid.net/Main_Page"&gt;OpenID&lt;/a&gt;, and &lt;a href="http://oauth.net/"&gt;oAuth&lt;/a&gt;. Together, it is possible to tie together many interaction modes, across a variety of services such as email, Twitter, Flickr, last.fm, or other specific Social Networks.&lt;/p&gt;
&lt;p&gt;Of particular interest to those creating sites that create/use user profile information, Celik gave a nice primer on sharing profile information through the &lt;a href="http://microformats.org/wiki/hcard-supporting-user-profiles"&gt;hCard microformats&lt;/a&gt; work he has spearheaded. If you aren&amp;#8217;t familiar with the &lt;a href="http://microformats.org/about/"&gt;microformats&lt;/a&gt; efforts, this is definitely something worth checking out.&lt;/p&gt;
&lt;p&gt;Profile information can be tied together via &lt;a href="http://microformats.org/wiki/hcard"&gt;hCard&lt;/a&gt; (which describes &amp;#8220;people&amp;#8221; information), &lt;a href="http://www.gmpg.org/xfn/" title="&amp;lt;span class=&amp;quot;caps&amp;quot;&amp;gt;XFN&amp;lt;/span&amp;gt;"&gt;&amp;gt;XHTML&lt;/span&gt; Friends Network&lt;/a&gt; (which covers &amp;#8220;relationship&amp;#8221; information), and linking profiles&amp;#8217; information together across the net using &lt;span class="caps"&gt;XFN&lt;/span&gt;&amp;#8217;s &lt;code&gt;rel me="me"&lt;/code&gt; attribute on your links. This is called &lt;a href="http://gmpg.org/xfn/and/"&gt;profile equivalency&lt;/a&gt; and Google&amp;#8217;s crawlers, among others, use these to build the the data for the &lt;a href="http://code.google.com/apis/opensocial/"&gt;OpenSocial Social Graph &lt;span class="caps"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Key Lessons&lt;/h2&gt;
&lt;p&gt;A variety of speakers shared key lessons they learned as they built their products, and these lessons drive how they see &amp;#8220;the future.&amp;#8221; Here are some highlights:&lt;/p&gt;
&lt;p&gt;Blaine Cook, from &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;, emphasized the need to simplify (&lt;a href="http://c2.com/xp/YouArentGonnaNeedIt.html"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;YAGNI&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;) and listen to users versus your developers, and encouraged everyone to check out their Ruby distributed queue server &lt;a href="http://rubyforge.org/projects/starling/"&gt;Starling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Leah Culver from &lt;a href="http://pownce.com/"&gt;Pownce&lt;/a&gt; shared some of the missteps they made introducing their APIs. Their first &lt;span class="caps"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/span&gt; was not well conceived, didn&amp;#8217;t provide access to enough data, and just didn&amp;#8217;t succeed with developers. For 2.0, they are spending time with developers, greatly opening up the data available to applications, permitting key data uploads (file transfers, note posting, etc.), supporting oAuth, and providing a &lt;a href="http://pownce.com/tools/"&gt;developer showcase&lt;/a&gt;. Culver indicated that all of these efforts are also in support of the interoperability and key building blocks discussed earlier.&lt;/p&gt;
&lt;p&gt;Emily Boyd from &lt;a href="http://www.rememberthemilk.com/"&gt;Remember the Milk&lt;/a&gt; gave a really great talk on the evolution if her To Do List service and the amazing amount of work two people can do who are passionate about a space. She is a fun example of a computer person adopting &amp;#8220;cool&amp;#8221; technologies or &amp;#8220;workarounds,&amp;#8221; &amp;#8220;because they are cool,&amp;#8221; and in this case, doing so at the benefit of her customers. One example was in pushing as much into client-side Javascript processing as possible, adopting Google&amp;#8217;s &lt;a href="http://gears.google.com/"&gt;Gears&lt;/a&gt; offline framework. Another novel feature was unofficial integration of task management with GMail (where no real &lt;span class="caps"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/span&gt; exists) through the use of the likes of &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;greasemonkey&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cal Henderson of &lt;a href="http://www.flickr.com/"&gt;Flickr&lt;/a&gt; gave one of his trademark talks, equal parts informative and good fun. At &lt;span class="caps"&gt;&lt;span class="caps"&gt;FOWA&lt;/span&gt;&lt;/span&gt;, Henderson focused on automation, monitoring, and incrementalism. At Flickr, they keep releases small and rapid, thereby keeping the amount that can go wrong as small as possible. His book, &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596102356/buildicom-20"&gt;Building Scalable Web Sites&lt;/a&gt; covers many of these techniques and suggestions.&lt;/p&gt;
&lt;p&gt;Gary Vaynerchuck of &lt;a href="http://tv.winelibrary.com/"&gt;wine library tv&lt;/a&gt; rounded out the day with his inspirational talk. He talked of the creation of his vlog, but most importantly, about the need to be passionate about your community (and wine!).&lt;/p&gt;
&lt;h2&gt;Worth it?&lt;/h2&gt;
&lt;p&gt;Overall, &lt;span class="caps"&gt;&lt;span class="caps"&gt;FOWA&lt;/span&gt;&lt;/span&gt; was a great opportunity to meet and greet many of the folks driving current Web 2.0 darlings, as well as mingle and share ideas with other entrepreneurs trying to create the next wave. I&amp;#8217;d recommend it if you are looking for events to add to your list of &amp;#8220;networking&amp;#8221; events, but skip it if you are looking for purely technical information (for that, &lt;a href="http://www.buildingwebapps.com/articles/15-barcamp-miami-2008"&gt;barcamp is a better choice than &lt;span class="caps"&gt;&lt;span class="caps"&gt;FOWA&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;p&gt;Many of the talks are available &lt;a href="http://www.futureofwebapps.com/2008/miami/pastevents.php"&gt;online as MP3 and slides&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Following and contributing to real-time chatter on Twitter at conferences, other events, and topics is much easier with twitter #tag, add &lt;a href="http://hashtags.org/"&gt;hashtags&lt;/a&gt; bot to enable it.&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xoCWQ3HSJ9E:I-WLSlVxrPY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xoCWQ3HSJ9E:I-WLSlVxrPY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xoCWQ3HSJ9E:I-WLSlVxrPY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=xoCWQ3HSJ9E:I-WLSlVxrPY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/xoCWQ3HSJ9E" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6432-future-of-web-apps-miami-2008</feedburner:origLink></entry>
  <entry>
    <title>Using Yahoo's User Interface Library Treeview in Rails</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/5bbx04Y-exw/6415-using-yahoo-s-user-interface-library-treeview" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6415-using-yahoo-s-user-interface-library-treeview</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>Our BuildingWebApps.com site organizes much of its information by assigning one or more categories from a domain specific taxonomy to each article, link, or other piece of content. A site visitor can browse the information in several ways, but one quick approach is via a category browser widget that appears on most content pages. The hierarchical tree view is implemented by embedding Yahoo's Open Source User Interface Library Treeview (aka YUI treeview, or just treeview here) into our RHTML.</summary>
    <content type="html">
&lt;p&gt;Our &lt;a href="http://www.buildingwebapps.com/"&gt;BuildingWebApps.com&lt;/a&gt; site organizes much of its information by assigning one or more categories from a domain specific taxonomy to each article, link, or other piece of content. A site visitor can browse the information in several ways, but one quick approach is via a category browser widget that appears on most content pages. The hierarchical tree view is implemented by embedding &lt;a href="http://developer.yahoo.com/yui/treeview/"&gt;Yahoo&amp;#8217;s Open Source User Interface Library Treeview&lt;/a&gt; (aka &lt;span class="caps"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/span&gt; treeview, or just treeview here) into our &lt;span class="caps"&gt;&lt;span class="caps"&gt;RHTML&lt;/span&gt;&lt;/span&gt;. As of this writing, &lt;span class="caps"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/span&gt; is available under a &lt;a href="http://developer.yahoo.net/yui/license.txt"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;BSD&lt;/span&gt;&lt;/span&gt; License&lt;/a&gt; and is part of a much larger, rich set of Javascript widgets and utility classes.&lt;/p&gt;
&lt;div style='float:left; width:200px; margin: 0 10px 5px 0'&gt;
&lt;p&gt;&lt;img src="/yui_article_1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The treeview widget is implemented in Javascript, has many visual and interaction behaviors that can be tuned, it can be skinned, and it can work with static or dynamic data sources.&lt;/p&gt;
&lt;p&gt;In our case, since our category data changes infrequently, we decided to implement a static data collection that we can cache, and which is loaded with the page in its entirety.&lt;/p&gt;
&lt;p&gt;Here is how I did it.&lt;/p&gt;
&lt;h2&gt;Step One: Grab The Source From Yahoo&lt;/h2&gt;
&lt;p&gt;After downloading the latest libary, I dropped the default Javascript and &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; files into our Rails app&amp;#8217;s public/javascripts and public/stylesheets directories, respectively. The &lt;span class="caps"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/span&gt; widget Javascript comes in several implementations: a debug version (treeview-debug.js) which is fully documented and instrumented, a production version (treeview.js), and an obfuscated, slimmed down version (treeview-min.js).&lt;/p&gt;
&lt;p&gt;A couple of supporting libraries are also required for utility code and event handling (yahoo.js and event.js, both available with -min.js variants.)&lt;/p&gt;
&lt;p&gt;Similarly, there are a number of stylesheets that are needed depending on the visual and interaction choices you make for your widget use. On the BuildingWebApps.com site, I wanted the control to act as a menu of sorts, such that only one category can be selected at once, and when I select a category in one part of the tree, I want any other prior choice to deselect. The treeview-menu.css contained the necessary defaults for this look and feel.&lt;/p&gt;
&lt;p&gt;Like the Javascript, you can grab minimal versions of some of these &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; files (labeled with -min postfixes) when available.&lt;/p&gt;
&lt;p&gt;One thing to note is that I customized some of our &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; to tweak the appearance for the site and snuck those snippets in our site &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; file instead.&lt;/p&gt;
&lt;p&gt;Finally, I needed to prepare the visual assets for the disclosure triangle and bullet graphics. The library comes with a default set of sprite GIFs that you can open in any image editor and customize as needed. After some quick editing, I installed our GIFs into our public/images directory and tweaked the &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; to point to the correct place.&lt;/p&gt;
&lt;h2&gt;Step 2: Creating My Views&lt;/h2&gt;
&lt;p&gt;Next, I proceeded to get my view environment ready for widget usage. First, I plugged my stylesheet and javascript tags into my common layout&amp;#8217;s header:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;%= stylesheet_link_tag 'treeview-menu' %&amp;amp;gt;
&amp;amp;lt;%= javascript_include_tag 'yahoo-min.js'%&amp;amp;gt;    
&amp;amp;lt;%= javascript_include_tag 'event-min.js'%&amp;amp;gt;
&amp;amp;lt;%= javascript_include_tag 'treeview-min.js'%&amp;amp;gt;    
&lt;/pre&gt;
&lt;p&gt;I then created a partial template file _nav_widget to hold the treeview setup:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;h2&amp;amp;gt;Browse &amp;amp;lt;img src="/images/icons-browse.gif" width="25" height="25" align="absmiddle" /&amp;amp;gt;&amp;amp;lt;/h2&amp;amp;gt;
&amp;amp;lt;div id="contentTreeDiv"&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;script type="text/javascript"&amp;amp;gt;
(function() {
&amp;amp;lt;%= category_tree_data_builder('category_data') %&amp;amp;gt;
&amp;amp;lt;%= yui_tree_builder('contentTreeDiv', 'category_data', item) %&amp;amp;gt;
})();
&amp;amp;lt;/script&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;When the page this code is embedded on loads, the anonymous Javascript function fires, and proceeds to run the Javascript that gets embedded in place here by my helper functions. This technique effectively name-spaces any of the code inside the scope of the anonymous function, protecting me from any inadvertent collisions. Once the Javascript produced by _yui_tree_builder_ executes, it replaces the div with id &amp;#8220;contentTreeDiv&amp;#8221; with the final treeview widget.&lt;/p&gt;
&lt;p&gt;With my partial ready to go, I am able to start using it in my various pages by the normal render techniques:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;% content_for :right_middle do %&amp;amp;gt;
	&amp;amp;lt;%= render :partial =&amp;amp;gt; '/categories/nav_widget', :locals =&amp;amp;gt; {:item =&amp;amp;gt; @category } %&amp;amp;gt;
&amp;amp;lt;% end %&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;The mysterious local variable &amp;#8220;item&amp;#8221; permits me to hint to the treeview where I am in the display hierarchy so I can start the treeview open and expanded to that category.&lt;/p&gt;
&lt;p&gt;As you can see, all of the magic is hidden in my helpers, _category_tree_data_builder_, which is responsible for constructing an array of data that is consumed by _yui_tree_builder_, which creates the Javascript that builds the widget.&lt;/p&gt;
&lt;h2&gt;Step 3: Inside The Helpers&lt;/h2&gt;
&lt;p&gt;My technique is inspired by &lt;a href="http://sonjayatandon.com/07-2006/how-to-integrate-a-yui-tree-with-rails/"&gt;Sonjaya Tandon&amp;#8217;s &lt;span class="caps"&gt;&lt;span class="caps"&gt;HOW&lt;/span&gt;&lt;/span&gt;-TO: Integrate a &lt;span class="caps"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/span&gt; tree with Rails&lt;/a&gt; article. I&amp;#8217;ve made some changes to start to support multiple treeviews and permit that &amp;#8220;hinting&amp;#8221; of where the user is when she navigates from one page with the widget to another (so the tree starts in an expanded mode at the appropriate category node).&lt;/p&gt;
&lt;p&gt;_category_tree_data_builder__ constructs the array of data from our taxonomy of categories. You would change this code to walk your model as appropriate. For BuildingWebApps.com, the Category model is built with the acts_as_tree model extension, so walking the tree is simple. This implementation is slightly unwound to make it easier to follow:&lt;/p&gt;
&lt;pre&gt;
def walk_category_recursive(level, parent)
  ret = ""
   parent.children.each do |node|
     ret += "#{level}, \'"
     ret += yield level, node
     ret += "\',\n"
     ret += walk_category_recursive(level + 1, node) { |lvl, n| yield lvl, n } unless node.children.empty?
  end
  ret
end

def category_tree_data_builder(tree_data)
  data = "var #{tree_data} = [" +
    walk_category_recursive(0, Category.root) {|lvl, node| link_to(h(truncate(node.title, (30 - lvl))), {:controller =&amp;amp;gt; 'topic', :action =&amp;amp;gt; 'show', :id =&amp;amp;gt; node}) }
  # chop off the last trailing comma
  data.chomp!.chop!
  return data + "];\n"
end
&lt;/pre&gt;
&lt;p&gt;Finally, we construct our Javascript code that builds the actual treeview widget:&lt;/p&gt;
&lt;pre&gt;
def yui_tree_builder(tree_div_id, tree_data, expanded_label)
  expanded_label = "NONE" if expanded_label.nil?
  return "var tree; \n" +
      "function #{tree_div_id}Init() {\n"+
      	"tree = new YAHOO.widget.TreeView(\"#{tree_div_id}\");\n"+
      	"addChildrenNodes(0, 0, tree.getRoot());\n"+
      	"tree.draw();\n"+
      "};\n"+
      "function addChildrenNodes(currLevel, nodeIndex, parent) { \n" +
       "var lastNode;\n"+
       "var level = currLevel;\n"+
       "while (nodeIndex &amp;amp;lt; #{tree_data}.length) {\n"+
           "var level = #{tree_data}[nodeIndex];\n"+
           "if (level == currLevel) {\n"+
               "nodeIndex++;\n"+
               "if (#{tree_data}[nodeIndex].indexOf(\"/#{expanded_label}-\") &amp;amp;lt; 0) {\n" + 
                  "lastNode = new YAHOO.widget.HTMLNode({html: \"&amp;amp;lt;div class='browserNaviNotSelected'&amp;amp;gt;\" + #{tree_data}[nodeIndex] + \"&amp;amp;lt;/div&amp;amp;gt;\"}, parent, false, true);\n"+
                  "lastNode.multiExpand = false;\n"+                    
                  "lastNode.nowrap = true;\n"+
                "} else {\n" +
                  "lastNode = new YAHOO.widget.HTMLNode({html: \"&amp;amp;lt;div id='browserNaviCenter'&amp;amp;gt;&amp;amp;lt;div id='browserNaviItem'&amp;amp;gt;\" +  #{tree_data}[nodeIndex] + \"&amp;amp;lt;/div&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;\"}, parent, true, true);\n"+
                  "lastNode.multiExpand = false;\n"+
                  "lastNode.nowrap = true;\n"+
                  "var p = parent;\n"+
                  "while (p != null) {\n"+
                    "p.expanded = true;\n"+
                    "p = p.parent;\n"+
                  "}\n"+
                "}\n"+
               "nodeIndex++;\n"+
           "} else if (level &amp;amp;lt; currLevel) {\n"+
               "return nodeIndex;\n"+
           "} else {\n"+
               "nodeIndex = addChildrenNodes(level, nodeIndex, lastNode);\n"+
           "}\n"+
       "}\n"+
       "return nodeIndex;\n"+
      "};\n"+
      "YAHOO.util.Event.onDOMReady(#{tree_div_id}Init);\n"
end
&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s pretty much it. Most of the tweaking that I&amp;#8217;ve done since putting this code together has been on the style side of things to improve the appearance. Peeking inside of the &lt;span class="caps"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/span&gt; code reveals a number of node types, and if none of them fit your needs, it is easy to derive your own functionality in no time.&lt;/p&gt;
&lt;p&gt;I will likely change the solution presented here if we ever dramatically grown our category taxonomy. Downloading the data en-masse isn&amp;#8217;t ideal from a scalability and bandwidth usage point of view. When the time comes, it would be relatively simple to partition the data set into levels or layers of the tree, and dynamically load what is needed when certain nodes are exposed. In the mean-time, the existing solution is simple.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=5bbx04Y-exw:DSrQHgO8AFE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=5bbx04Y-exw:DSrQHgO8AFE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=5bbx04Y-exw:DSrQHgO8AFE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=5bbx04Y-exw:DSrQHgO8AFE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/5bbx04Y-exw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6415-using-yahoo-s-user-interface-library-treeview</feedburner:origLink></entry>
  <entry>
    <title>Selling Friends: Scaling a High-Traffic Rails Application</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/k1hRF7P-H8Y/6503-selling-friends-scaling-a-high-traffic-rails" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6503-selling-friends-scaling-a-high-traffic-rails</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>At the recent Silicon Valley Ruby Conference, Friends for Sale developer Alex Le outlined the approach they've taken to scaling up to deliver an impressive 300 million page views per month for their Rails-based Facebook application.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; width: 210px'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/alex_le.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;At the recent Silicon Valley Ruby Conference, Friends for Sale developer Alex Le outlined the approach they&amp;#8217;ve taken to scaling up to deliver an impressive 300 million page views per month for their Rails-based Facebook application.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.facebook.com/applications/Friends_For_Sale!/7019261521"&gt;Friends for Sale&lt;/a&gt; is currently the #6 most popular application on Facebook. The application describes itself as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Buy and sell your friends as pets! You can make your pets poke, send gifts, or just show off for you. Make money as a shrewd pets investor or as a hot commodity!&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I guess I there&amp;#8217;s something here I don&amp;#8217;t quite get &amp;#8212; but in any case it has become perhaps the highest-traffic Rails app, delivering at least 50% more page views per month than yellowpages.com.&lt;/p&gt;
&lt;p&gt;The app was created by the ironically named Serious Business Inc. The initial version was built in 10 days by Alex Le and Siqi Chen, using the &lt;a href="http://rubyforge.org/projects/rfacebook/"&gt;RFacebook gem&lt;/a&gt;, and was launched on 11/1/07. Alex had previously worked on the rebuilding of yellowpages.com as a Rails application.&lt;/p&gt;
&lt;p&gt;Referring to the oft-cited scaling aphorism, Alex asserted &amp;#8220;Don&amp;#8217;t scale until you need to&amp;#8230; unless you&amp;#8217;re on Facebook!&amp;#8221; They had scalability problems on their first day because of the speed at which the audience ramped up. By the end of the first month they were delivering 1 million page views per day; by the end of the third month, they hit 10 million per day. They currently have 7 million users and 650,000 unique visitors per day.&lt;/p&gt;
&lt;p&gt;Scaling to this traffic level required both adding lots of servers and tuning the database. They started out at Slicehost, and switched to &lt;a href="http://softlayer.com"&gt;SoftLayer&lt;/a&gt; when they needed more servers. Their decision to use SoftLayer was driven, in part, by the speed with which they could get them set up &amp;#8212; 2 hours. Alex encouraged everyone to start with a hosting provider that can scale with you, to reduce the pain when traffic grows.&lt;/p&gt;
&lt;p&gt;After two months, they hired a database administrator to handle the database tuning. Alex recommended using the Rails &lt;a href="http://agilewebdevelopment.com/plugins/query_analyzer"&gt;Query Analyzer&lt;/a&gt; plugin, and to index only the fields that you need to. He noted that while Active Record makes it easy to get the application going, it can get in the way when you need to optimize your database performance. They use Dr. Nic&amp;#8217;s &lt;a href="http://magicmodels.rubyforge.org/magic_multi_connections/"&gt;Magic Multi Connections&lt;/a&gt; plugin to handle the database connections, with some monkey-patching to fix issues they found; they plan to release their plugin code soon.&lt;/p&gt;
&lt;p&gt;Their current server configuration includes:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;One front-end server running &lt;a href="http://nginx.net/"&gt;nginx&lt;/a&gt; with &lt;a href="http://github.com/gnosek/nginx-upstream-fair/tree/master"&gt;fair&lt;/a&gt; for load balancing.&lt;/li&gt;
	&lt;li&gt;Eleven application servers, each with 8G &lt;span class="caps"&gt;&lt;span class="caps"&gt;RAM&lt;/span&gt;&lt;/span&gt; and four 2.4 GHz processors, running 16 Mongrel instances on each one (that&amp;#8217;s 176 Mongrels!), with 4G on each server for &lt;a href="http://danga.com/memcached/"&gt;memcached&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;One master database server and three slaves, each with eight 2.3 GHz processors and 32G &lt;span class="caps"&gt;&lt;span class="caps"&gt;RAM&lt;/span&gt;&lt;/span&gt;, using 10K &lt;span class="caps"&gt;&lt;span class="caps"&gt;RPM&lt;/span&gt;&lt;/span&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;SCSI&lt;/span&gt;&lt;/span&gt; drives in a Raid 1+0 configuration, running MySQL 5.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Their next step is to seek more performance from their existing hardware. Toward that end, they&amp;#8217;re planning to move from fair to &lt;a href="http://rubyforge.org/projects/qrp/"&gt;qrp&lt;/a&gt; (queueing reverse proxy) for load balancing, and they&amp;#8217;re exploring alternative implementations of Mongrel that have faster threading models.&lt;/p&gt;
&lt;p&gt;They also cache extensively. Serialized models are stored in memcached, using write-through caching. They moved logic to view helpers to simplify the use of fragment caching.&lt;/p&gt;
&lt;p&gt;Serious Business has been &lt;a href="http://jobs.37signals.com/jobs/3436"&gt;recruiting&lt;/a&gt; for Rails developers, and in these ads they claim they are building the world&amp;#8217;s largest Rails cluster. Maybe selling friends isn&amp;#8217;t such a bad idea.&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=k1hRF7P-H8Y:XSbRK8y4_kw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=k1hRF7P-H8Y:XSbRK8y4_kw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=k1hRF7P-H8Y:XSbRK8y4_kw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=k1hRF7P-H8Y:XSbRK8y4_kw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/k1hRF7P-H8Y" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6503-selling-friends-scaling-a-high-traffic-rails</feedburner:origLink></entry>
  <entry>
    <title>Exception Handling and Old URLs</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/zqvprVpAQ5A/6396-exception-handling-and-old-urls" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6396-exception-handling-and-old-urls</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Whenever I deploy a Rails site, I install the exception notification plugin so I get an email if a user provokes a bug I hadn't found. It's a piece of cake to install ...</summary>
    <content type="html">
&lt;p&gt;Whenever I deploy a Rails site, I install the exception notification plugin so I get an email if a user provokes a bug I hadn&amp;#8217;t found. It&amp;#8217;s a piece of cake to install:&lt;/p&gt;
&lt;p&gt;1. Install the plugin&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ruby script/plugin install exception_notification&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2. Include the plugin in your ApplicationController (in the application.rb file)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;include ExceptionNotifiable&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3. Add one line to your environment.rb file to specify where to send the email&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ExceptionNotifier.exception_recipients = %w(person1@domain.com person2@domain.com)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4. Make sure you have ActionMailer configured (to use either sendmail or &lt;span class="caps"&gt;&lt;span class="caps"&gt;STMP&lt;/span&gt;&lt;/span&gt;), which you&amp;#8217;ll already have done if your app sends email for any purpose.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s this? Errors already?&lt;/h2&gt;
&lt;p&gt;A few minutes after I first installed the Exception Notification plugin, I checked my inbox and found a dozen error emails from the site! After a brief moment of panic, I realized that all were coming from search engine spiders, and that the URLs were all invalid. I had replaced an old, crufty, static &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; site, and the spiders were rechecking pages they had indexed in the past.&lt;/p&gt;
&lt;p&gt;So the next question was what to do with the old URLs. I could remap each &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; to the most appropriate page on the new site, but the old site got little traffic and there wasn&amp;#8217;t a clear mapping between the two sets of pages, so it hardly seemed worth it. I decided to map index.html to the new home page, since many people might have bookmarked that page, and it was clear what it should map to. As for everything else, I wanted a way to tell the spiders to stop trying to index them, and to tell anyone who accessed them that this was no longer a valid &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; and they should explore the new site.&lt;/p&gt;
&lt;p&gt;The heart of the fix is to add a few lines to routes.rb. Fortunately, the old site design had put all the &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; pages except for the index page into a directory called html. There were also some &lt;span class="caps"&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt;&lt;/span&gt; files, conveniently in a directory named web_pdfs.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the routes, which I added at the end just before the default route:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
map.connect '/index.html', :controller =&amp;amp;gt; 'page', :action =&amp;amp;gt; 'home'
map.connect '/html/*any', :controller =&amp;amp;gt; 'page', :action =&amp;amp;gt; 'oldpage'
map.connect '/web_pdfs/*any', :controller =&amp;amp;gt; 'page', :action =&amp;amp;gt; 'oldpage'
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;I have a controller called page_controller that manages the public parts of the site. The first route simply maps index.html to the home page action.&lt;/p&gt;
&lt;p&gt;The second route maps any &lt;span class="caps"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt; in the html directory to a new page, which I called simply &amp;#8220;oldpage&amp;#8221;. The oldpage.rhtml file simply has some text telling the visitor that this page no longer exists, and gives them some suggestions for exploring the new site.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;*any&amp;#8221; in the route definition absorbs whatever comes after &amp;#8220;/html/&amp;#8221;. With this technique, I don&amp;#8217;t have to worry about whether there might be subdirectories within html, or what the file name extensions might be.&lt;/p&gt;
&lt;p&gt;The final piece was to tell the spiders not to bother with these pages any more. I didn&amp;#8217;t want to use a redirect, because the page to which I wanted to redirect the user wasn&amp;#8217;t the new permanent page, but rather one that explained that the site had been changed. I decided to set the &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; header to the &amp;#8220;gone&amp;#8221; status code (410). This just takes one line in the page controller oldpage action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
def oldpage
  render :template =&amp;amp;gt; 'page/oldpage', :status =&amp;amp;gt; :gone
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eventually the spiders will stop spidering these old pages, but since index.html will still lead to the new home page without any error code, they will find all the new pages from there.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=zqvprVpAQ5A:_RyPJoyGYTU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=zqvprVpAQ5A:_RyPJoyGYTU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=zqvprVpAQ5A:_RyPJoyGYTU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=zqvprVpAQ5A:_RyPJoyGYTU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/zqvprVpAQ5A" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6396-exception-handling-and-old-urls</feedburner:origLink></entry>
  <entry>
    <title>Validating Email Addresses with Ruby</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/xwfaYb-GZ9E/6392-validating-email-addresses-with-ruby" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6392-validating-email-addresses-with-ruby</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>In any application in which a user enters an email address, there is the very real possibility that the user will make a typo and your application will end up with an invalid address. You can have them enter it twice, but this seems clunky. And you can, of course, send an email with an activation link, which ...</summary>
    <content type="html">
&lt;p&gt;In any application in which a user enters an email address, there is the very real possibility that the user will make a typo and your application will end up with an invalid address. You can have them enter it twice, but this seems clunky. And you can, of course, send an email with an activation link, which provides the only true validation, but there&amp;#8217;s no need to bother sending the email if you know the address is no good. Furthermore, once you&amp;#8217;re past the page where the user enters their email address, you&amp;#8217;ve missed your chance to tell them there&amp;#8217;s something wrong and they should correct it.&lt;/p&gt;
&lt;p&gt;So you really should do what you can to validate the address when the user enters it. I recently made a simple addition to my applications that helps a lot: verify that the domain name is valid.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s surprisingly easy to do &amp;#8212; especially with a little help from Peter Cooper&amp;#8217;s excellent &lt;a href="http://www.mslater.com/2007/5/26/great-new-ruby-book"&gt;Beginning Ruby&lt;/a&gt;, which has a very useful chapter on network programming. The following code is adapted from his examples:&lt;/p&gt;
&lt;pre&gt;
require 'resolv'
def validate_email_domain(email)
      domain = email.match(/\@(.+)/)[1]
      Resolv::DNS.open do |dns|
          @mx = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
      end
      @mx.size &amp;amp;gt; 0 ? true : false
end
&lt;/pre&gt;
&lt;p&gt;This example makes use of the Ruby standard library &amp;#8220;resolv&amp;#8221;, so you need to require it first.&lt;/p&gt;
&lt;p&gt;The first step is to separate the domain name from the rest of the email address. The regular expression captures the part of the string that follows the @ symbol.&lt;/p&gt;
&lt;p&gt;Then the code creates a new &lt;span class="caps"&gt;&lt;span class="caps"&gt;DNS&lt;/span&gt;&lt;/span&gt; resolver object and queries the resolver for an MX (mail exchanger) resource at the specified domain. This returns an array, which will be empty if there is no MX record for the domain.&lt;/p&gt;
&lt;p&gt;(Note: In a previous version of this article, I used Resolv.getaddress to see if there is a &lt;span class="caps"&gt;&lt;span class="caps"&gt;DNS&lt;/span&gt;&lt;/span&gt; entry for the domain, instead of checking for an MX record. This approach works most of the time, but it rejects any domain for which there is no A record. If a domain is used only for email and not for a web server, there might not be an A record. Also, some domains have an A record only for www.domain.com, which will also fail the simple getaddress test.)&lt;/p&gt;
&lt;p&gt;You can use something like the following in the validate method within the appropriate model:&lt;/p&gt;
&lt;pre&gt;
unless email.blank?
    unless email =~ /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
        errors.add(:email, "Your email address does not appear to be valid")
    else
        errors.add(:email, "Your email domain name appears to be incorrect") unless validate_email_domain(email)
    end
end
&lt;/pre&gt;
&lt;p&gt;I first check to make sure the email address is not blank, because that&amp;#8217;s detected by a simple validates_presence_of :email statement that produces a different error message.&lt;/p&gt;
&lt;p&gt;Then I make sure that the email address is at least syntactically reasonable, with a rather ugly regular expression, before bothering to check the &lt;span class="caps"&gt;&lt;span class="caps"&gt;DNS&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;It should be noted that the regex I use here isn&amp;#8217;t designed to cover all of the &lt;a href="http://rfc.net/rfc2822.html"&gt;RFC2822&lt;/a&gt; cases, nor with other &lt;span class="caps"&gt;&lt;span class="caps"&gt;RFC&lt;/span&gt;&lt;/span&gt; drafts dealing with non-&lt;span class="caps"&gt;&lt;span class="caps"&gt;ASCII&lt;/span&gt;&lt;/span&gt; addressing.&lt;/p&gt;
&lt;p&gt;An even better approach would be to use an observer to validate the address with an Ajax call before the user submits the form.&lt;/p&gt;
&lt;p&gt;It is possible to take this a step further by sending the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SMTP&lt;/span&gt;&lt;/span&gt; server referenced in the MX record a &amp;#8220;&lt;span class="caps"&gt;&lt;span class="caps"&gt;RCPT&lt;/span&gt;&lt;/span&gt; TO:&amp;#8221; command. In theory, this would check that the user name is valid as well as the domain name. This takes additional time, however, and I&amp;#8217;ve read that the response from mail servers is often not reliable. If anyone has tried this, I&amp;#8217;d appreciate any feedback on how well it worked.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xwfaYb-GZ9E:0j-Q3SeKZ_s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xwfaYb-GZ9E:0j-Q3SeKZ_s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=xwfaYb-GZ9E:0j-Q3SeKZ_s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=xwfaYb-GZ9E:0j-Q3SeKZ_s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/xwfaYb-GZ9E" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6392-validating-email-addresses-with-ruby</feedburner:origLink></entry>
  <entry>
    <title>Using SSH Keys to Speed Login</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/GyQoAQJuLgc/6397-using-ssh-keys-to-speed-login" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6397-using-ssh-keys-to-speed-login</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>With a basic SSH setup, you have to enter your password every time you log in to the server, which is not unreasonable from a security perspective. But if just use a password, you'll end up typing that it over and over again, even for a single deployment. Fortunately, there is a mechanism to avoid this ...</summary>
    <content type="html">
&lt;p&gt;With a basic &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; setup, you have to enter your password every time you log in to the server, which is not unreasonable from a security perspective. But if you want to automate tasks and use deployment tools such as &lt;a href="http://manuals.rubyonrails.com/read/book/17"&gt;Capistrano&lt;/a&gt;, you&amp;#8217;ll end up typing that password over and over again, even for a single deployment process. Fortunately, there is a mechanism to avoid this while still preserving good security. But, as with most such things in Windows, it takes a little effort to set it up. (Things are a little simple on Macs, which we&amp;#8217;ll cover in a future article.)&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; authentication uses &lt;a href="http://en.wikipedia.org/wiki/Public-key_cryptography"&gt;public key cryptography&lt;/a&gt;, in which you have a private key available only to you on your local system, and a matching public key that can be published on your server. Authentication software can confirm that the public and private keys match, but hackers cannot derive your private key from your public key. Once you set up a public-private key pair, these keys can be used to authenticate your &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; sessions, and you won&amp;#8217;t ever have to type your password again.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a couple different programs you can use to accomplish this; I&amp;#8217;m going to explain how to do it with PuTTY and its associated programs, PuTTYgen and Pageant. If you installed the full PuTTY package, you&amp;#8217;ll have all three programs already installed. If not, &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;download the installer&lt;/a&gt; and run it now. (Be sure to get the full package, under the heading &amp;#8220;A Windows installer for everything except PuTTYtel,&amp;#8221; and not just putty.exe.)&lt;/p&gt;
&lt;h1&gt;Creating Your Keys with PuTTYgen&lt;/h1&gt;
&lt;p&gt;To create your public-private key pair, run PuTTYgen. There&amp;#8217;s several types of keys, but &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt;-2 &lt;span class="caps"&gt;&lt;span class="caps"&gt;RSA&lt;/span&gt;&lt;/span&gt; is the most common and is selected by default. (If this doesn&amp;#8217;t work, you&amp;#8217;ll need to check with your host to see what type of key their &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; server is expecting.) The number of bits defaults to 1024, which is fine. So all you have to do in the PuTTYgen window is click the Generate button, and then wiggle the mouse around a bit. The mouse movements generate random data that ensures that your key is unique.&lt;/p&gt;
&lt;p&gt;When PuTTYgen is done creating the key, it will show a long string of characters that make up the public key. Select this text and paste it into a file, named something like id.pub (using notepad or any simple text editor). I made a folder at the root level of my C drive called &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; to store these keys and other related info, but you can put it anywhere you can find it later. (Note: you can also click the Save Public Key button and enter a file name, but &lt;strong&gt;this file won&amp;#8217;t work&lt;/strong&gt; as an alternative to the id.pub file we generated with cut-and-paste. It includes line break characters that confuse the server-side &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; code.)&lt;/p&gt;
&lt;p&gt;Now you need to save your private key. If you just click the Save Private Key button, PuTTYgen will ask if you really want to save it without a passphrase, because we didn&amp;#8217;t enter one. Here you have a choice to make between convenience and security.&lt;/p&gt;
&lt;p&gt;The passphrase is essentially a password for accessing the key. Once you have your public key uploaded to your server (which we&amp;#8217;ll do shortly), anyone who has access to your private key will have access to your server. If you use password protection on your PC, and you&amp;#8217;re the only one with access to it, you might be comfortable going without a passphrase. But it is safest to use a passphrase, and we&amp;#8217;ll soon see how you can make it so you only need to enter it once each time you boot your system. So to set a passphrase and save the private key:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Enter it twice, once in the Key Passphrase field and once in the Confirm Passphrase field. Keep in mind that this passphrase is essentially the key to accessing your server, so make it a robust password.&lt;/li&gt;
	&lt;li&gt;Click the Save Private Key button, and enter a file name (no extension) for your private key. The .ppk extension is automatically appended.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You now have your key pair and are done with PuTTYgen. Next you need to upload your public key to your server and set up your PC to access your private key.&lt;/p&gt;
&lt;h1&gt;Uploading Your Public Key&lt;/h1&gt;
&lt;p&gt;The details of uploading your public key may vary depending on the server configuration. The instructions below are for &lt;a href="http://www.railsmachine.com"&gt;Rails Machine&lt;/a&gt; and are derived from the Mac and Linux oriented instructions they provide.&lt;/p&gt;
&lt;p&gt;Open an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; session to your server (using PuTTy, or another client if you prefer, as described in my &lt;a href="http://www.mslater.com/2006/12/8/remote-linux-admin-for-windows-users"&gt;previous post&lt;/a&gt;.) You probably have more than one user account; in my case, following the recommended practices from the Rails Machine folks, I have a root account that I never log into directly, and regular user accounts of Michael and Deploy. The Deploy account is the one I use for almost all communication with the server. So log into that account, or its equivalent for your setup. You&amp;#8217;ll have to manually enter the password one last time.&lt;/p&gt;
&lt;p&gt;Now, in the shell window that is connected to your server, create a directory for the private key file:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mkdir ~/.ssh&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This creates a directory named .ssh within your home directory, which is where the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; server will look for the public key.&lt;/p&gt;
&lt;p&gt;Now set the permissions for this directory so you, but only you, have all privileges:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;chmod 700 ~/.ssh&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now you have a directory on your server to hold your public key, and you need to move the key up there. There&amp;#8217;s various tools you can use to do this. One tool you should become comfortable with is scp, or secure copy. It is not built in to Windows, but there is a version of it that comes with PuTTY, called pscp. If you add the path to the PuTTY program directory to your system path, you&amp;#8217;ll be able to use pscp in any command window. (You may also want to install a set of Unix-style utilities; you can install the entire &lt;a href="http://www.cygwin.com"&gt;Cygwin&lt;/a&gt; environment, or if you want something lighter weight just for &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt;-related tasks, get just the &lt;a href="http://sshwindows.sourceforge.net/"&gt;OpenSSH&lt;/a&gt; utilities. In either case, make sure to add to your Windows system path the folder in which these programs are stored, so you can use them from any command window without having to type their full path.)&lt;/p&gt;
&lt;p&gt;To copy the public key, follow these steps:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Open a Windows shell in the folder in which you&amp;#8217;ve stored your public key. (If you installed the &lt;a href="http://download.microsoft.com/download/whistler/Install/2/WXP/EN-US/CmdHerePowertoySetup.exe"&gt;Command Here&lt;/a&gt; utility as I recommended in the previous article, you can just right-click the folder and choose Open Command Window Here.)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;In the command window, type&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;pscp id.pub username@hostname.com:~/.ssh/authorized_keys&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Of course, you&amp;#8217;ll need to replace &amp;#8220;username&amp;#8221; with your actual user name, and &amp;#8220;hostname.com&amp;#8221; with the name of your server. If you&amp;#8217;ve named your public key something other than id.pub, replace that name as well. Finally, if you&amp;#8217;re using scp from OpenSSH instead of PuTTY&amp;#8217;s pscp, drop the p in the command name.) This will copy your public key to a file called authorized_keys in the .ssh directory in your home directory.&lt;/p&gt;
&lt;p&gt;Finally, to make the key file a little more secure, go back to your &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; window (remember, we started there but then switched to the Windows console), and type:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;chmod 600 ~/.ssh/authorized_keys&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This ensures that only the owner of this file (that&amp;#8217;s the user name you began your &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; session with) can read or write it.&lt;/p&gt;
&lt;h1&gt;Making Your Private Key Available in Windows&lt;/h1&gt;
&lt;p&gt;OK, we&amp;#8217;re almost there. Now we need to enable Windows programs making &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; connections to access your private key file. You could set PuTTY to use the key file, but that doesn&amp;#8217;t buy you much, since it will ask for the passphrase every time you open a connection, and it won&amp;#8217;t be available to other programs (such as Capistrano). So, you need to use another program called Pageant, which is installed along with PuTTY, to load the key into memory and make it available to other programs.&lt;/p&gt;
&lt;p&gt;You can run Pageant directly via Start &amp;gt; All Programs &amp;gt; PuTTY &amp;gt; Pageant, and then you can tell Pageant to load your private key. But assuming you want the private key to always be available, you want it to load automatically upon startup. To do so, create a text file called load_private_key.bat (or whatever), with the following contents:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;start &amp;#8220;Pageant&amp;#8221; &amp;#8220;c:/Program Files/PuTTY/Pageant.exe&amp;#8221; c:/ssh/id.ppk&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that you&amp;#8217;ll need to change the path to Pageant.exe if you didn&amp;#8217;t install PuTTY in its default location. The id.ppk file is the private key file that you generated from PuTTYgen. (Using the &amp;#8220;start&amp;#8221; command, rather than simply providing the path to Pageant directly, prevents a &lt;span class="caps"&gt;&lt;span class="caps"&gt;DOS&lt;/span&gt;&lt;/span&gt; window from being left on the screen. Thanks to Tim Jervis for this tip.)&lt;/p&gt;
&lt;p&gt;Finally, add this batch file to your startup tasks (Click Startup &amp;gt; All Programs &amp;gt; right click on Startup and choose Open, then right-click the load_private_key.bat file, drag it into the startup folder, and choose Create Shortcut from the menu that appears when you release the mouse).&lt;/p&gt;
&lt;p&gt;Now, when you reboot your system, the batch file will run, Pageant will load your private key, and you&amp;#8217;ll be prompted for the passphrase that you specified when you created the key. Enter this passphrase just this once, and your private key is now available to all &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; functions. When you shut your computer down, everything is secure again.&lt;/p&gt;
&lt;h1&gt;Setting up Subversion&lt;/h1&gt;
&lt;p&gt;If you&amp;#8217;re using Subversion, you need to take one more step to enable it to use the private key generated by PuTTYgen: adding a line to Subversion&amp;#8217;s configuration file.&lt;/p&gt;
&lt;p&gt;Subversion&amp;#8217;s configuration file is located in the Application Data directory under your user account. The full path is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\Documents and Settings\{your windows user name}\Application Data\Subversion\config&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that Application Data is a hidden folder, so to locate this file you must have Windows set to show hidden files and folders.&lt;/p&gt;
&lt;p&gt;Open the config file in any plain text editor (such as Notepad) and add the following line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ssh = $SVN_SSH plink.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;plink.exe is the command-line link setup program that is included with PuTTY.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll also need to make sure that the PuTTY directory is listed in your system&amp;#8217;s Path.&lt;/p&gt;
&lt;p&gt;Unfortunately, plink insists on popping up a &lt;span class="caps"&gt;&lt;span class="caps"&gt;DOS&lt;/span&gt;&lt;/span&gt; window, which is annoying. If anyone knows how to stop it from doing this, please let me know!&lt;/p&gt;
&lt;h1&gt;You&amp;#8217;re Done!&lt;/h1&gt;
&lt;p&gt;That was simple, wasn&amp;#8217;t it? :-)  This may seem like a lot of trouble to go to just to avoid having to type your password, but once you&amp;#8217;ve set this up once, you&amp;#8217;re done. And if you&amp;#8217;re using an automated deployment tool such as Capistrano, you&amp;#8217;d have to type your password multiple times for a single deployment (since one deployment involved multiple &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; commands and other actions); with this setup, it can be fully automated.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=GyQoAQJuLgc:rJJo4FJW5cA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=GyQoAQJuLgc:rJJo4FJW5cA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=GyQoAQJuLgc:rJJo4FJW5cA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=GyQoAQJuLgc:rJJo4FJW5cA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/GyQoAQJuLgc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6397-using-ssh-keys-to-speed-login</feedburner:origLink></entry>
  <entry>
    <title>Understanding Ruby on Rails</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/Y8REbrP-zAY/6400-understanding-ruby-on-rails" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6400-understanding-ruby-on-rails</id>
    <updated>2008-04-22T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>If you're new to Ruby on Rails, you may be struggling to understand just what Rails is, what it can do for you, and what you need to learn to use it effectively. In this article, we'll explain just that.</summary>
    <content type="html">
&lt;p&gt;If you&amp;#8217;re new to Ruby on Rails, you may be struggling to understand just what Rails is, what it can do for you, and what you need to learn to use it effectively. In this article, we&amp;#8217;ll take a quick romp through the various aspects of Rails. We&amp;#8217;ve sprinkled links liberally, so you can use it as an annotated table of contents for the rest of the site.&lt;/p&gt;
&lt;h2&gt;What is Ruby on Rails?&lt;/h2&gt;
&lt;p&gt;&lt;a href="/topic/show/5-ruby-on-rails"&gt;Ruby on Rails&lt;/a&gt; encompasses a number of technologies, and some philosophy as well. This can make it challenging to get your arms around just what Ruby on Rails is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="/topic/show/6-ruby"&gt;Ruby&lt;/a&gt;&lt;/strong&gt; is a programming language. By itself, there&amp;#8217;s nothing about Ruby that is specific to web applications.&lt;/p&gt;
&lt;p&gt;Ruby is a modern, object-oriented, dynamic language. In Ruby, everything is an object &amp;#8212; even a number is an object that has methods. Ruby is dynamic; data types are assigned dynamically, and you can extend the language itself as it is executing, defining classes, adding methods, and so forth.&lt;/p&gt;
&lt;p&gt;Ruby has a very clean, minimalist syntax. This, combined with its dynamic nature, makes it especially suitable for creating extensions to the language that enable your programs to read almost like English.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="/topic/show/5-ruby-on-rails"&gt;Rails&lt;/a&gt;&lt;/strong&gt; is a framework for writing web applications in Ruby. The term &amp;#8220;Rails&amp;#8221; is commonly used to refer to &amp;#8220;Ruby on Rails,&amp;#8221; which is the official name of the framework.&lt;/p&gt;
&lt;h2&gt;Why Use Rails?&lt;/h2&gt;
&lt;p&gt;If the application you are building falls into the very large sweet spot for which Rails works well, there&amp;#8217;s no faster way to write it &amp;#8212; once you&amp;#8217;re up-to-speed on the framework. There&amp;#8217;s a sizable learning curve to comprehend the Rails framework, but once you have the basics of it down, you&amp;#8217;ll be able to produce robust, fully customized applications more quickly than with any other technology.&lt;/p&gt;
&lt;p&gt;Because the Rails approach eliminates a lot of the drudgery of writing applications in languages such as Java, and because it makes changes easy and allows you to write expressive, readable code that is easy to maintain, it is simply more fun to build Rails applications. When coding is more fun, you&amp;#8217;ll write better code.&lt;/p&gt;
&lt;p&gt;Because Rails requires less code than most other approaches, you can produce a given application with fewer people. Smaller teams are more efficient than larger ones, multiplying the productivity gains of using Rails.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s also a great Rails community, so there&amp;#8217;s lots of open-source plugins and even complete applications, plus countless blogs and other information sources. It&amp;#8217;s an enthusiastic, helpful, programmer-centric community that puts a high priority both on building great applications and on having fun while you&amp;#8217;re doing it.&lt;/p&gt;
&lt;h2&gt;When Not to Use Rails&lt;/h2&gt;
&lt;p&gt;Rails is not the answer to every problem. Here&amp;#8217;s a few situations in which it is probably not the best approach:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;If you&amp;#8217;re new to Rails but are already up-to-speed in another technology, and the app you&amp;#8217;re building isn&amp;#8217;t too large, you&amp;#8217;ll get the work done more quickly by sticking with what you know. This is the major factor that stops most developers from switching to Rails. If you&amp;#8217;re building a large application, or think longer term, however, working your way up the Rails learning curve is very worthwhile.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;If you can create the application using something like Joomla, in which you can do a lot without writing any code at all, that&amp;#8217;s probably the quickest approach. You loose a lot of flexibility, however.&lt;/li&gt;
	&lt;li&gt;If the application needs to perform tremendous amounts of computation, the relatively slow speed of Ruby may be a disadvantage. This is quite rare, however, and you can always move the inner loops into a language such as C.&lt;/li&gt;
	&lt;li&gt;If you expect to have extremely high traffic, your server costs may be higher with a Rails application, and you&amp;#8217;ll have to do more innovating beyond what the framework gives you automatically. Then again, the time you save building the application may still make it a worthwhile trade-off.&lt;/li&gt;
	&lt;li&gt;If you have to share a legacy database with existing code, so you can&amp;#8217;t restructure it, it may be hard to make Rails work with it.&lt;/li&gt;
	&lt;li&gt;If you&amp;#8217;re building a static site, Rails is probably overkill. Even so, the templating engine in Rails is very useful for such sites, the built-in caching features can eliminate the need to run the Rails code on most accesses, and you can easily build in your own content-management features. But it is more expensive to host Rails sites than static sites, and there&amp;#8217;s a lot more you need to understand to build them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can probably tell by now, we think Rails is a great solution for the vast majority of web applications.&lt;/p&gt;
&lt;h2&gt;The Rails Philosophy&lt;/h2&gt;
&lt;p&gt;Before we get into the specifics of what Rails is composed of, it is helpful to understand the philosophy that underlies its approach.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s two terms you&amp;#8217;ll hear a lot with regard to Rails: &amp;#8220;convention over configuration&amp;#8221; and &amp;quot;&lt;span class="caps"&gt;DRY&lt;/span&gt; (don&amp;#8217;t repeat yourself).&lt;/p&gt;
&lt;p&gt;Convention over configuration is a very important principle behind Rails. It goes hand-in-hand with another attribute of Rails, that it is &amp;#8220;opinionated software&amp;#8221;. The Rails design embodies lots of opinions about how you should structure your code, name your classes and files, and organize your database tables. There are methods to override most of these conventions, but if you go with the flow and follow the conventions, then you can avoid almost all configuration code. That&amp;#8217;s convention over configuration &amp;#8212; and the payoff is huge.&lt;/p&gt;
&lt;p&gt;Keeping your code &lt;span class="caps"&gt;&lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/span&gt; means avoiding repetition. In its simplest form, it means that if you need the same code in two places, put it in a method so you can write it once and call if from both places. It sometimes increases the amount of work it takes to write your code initially, but it save headaches in the long run. There&amp;#8217;s various facilities in Rails to encourage this, but it is something you need to pay attention to when writing your code.&lt;/p&gt;
&lt;p&gt;In the past year or so, the Rails community has also leaned heavily toward &lt;a href="/topic/show/105-rest"&gt;RESTful&lt;/a&gt; architecture. There&amp;#8217;s no requirement to use a &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt; design, but Rails is increasingly encouraging you to do so, and providing tools to make it easier.&lt;/p&gt;
&lt;h2&gt;Aspects of Rails&lt;/h2&gt;
&lt;p&gt;Rails is designed to make it easy and fun to create interactive, reliable, database-backed web applications. Rails is a set of programming libraries, but it is more than that &amp;#8212; it is an approach to developing web applications. These are the major aspects of Rails:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Rails implements the &lt;a href="/topic/show/40-model-view-controller-mvc-architecture"&gt;model-view-controller&lt;/a&gt; (&lt;span class="caps"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/span&gt;) pattern for application design. Your application code is divided into models, which deal with the database and manage the data; views, which present present data to the user and allow the user to interact with the application; and controllers, which mediate between the two.&lt;/li&gt;
	&lt;li&gt;Rails provides base classes from which your &lt;a href="/topic/show/8-models"&gt;model&lt;/a&gt; and &lt;a href="/topic/show/9-controllers"&gt;controller&lt;/a&gt; classes inherit. This endows your classes with a great deal of capability without writing a single line of code beyond the class declaration.&lt;/li&gt;
	&lt;li&gt;Rails includes &lt;a href="/topic/show/73-active-record"&gt;Active Record&lt;/a&gt;, a module that provides an Object Relational Model (&lt;span class="caps"&gt;&lt;span class="caps"&gt;ORM&lt;/span&gt;&lt;/span&gt;) that automatically instantiates Ruby objects from your database tables. Your code never has to touch the database directly; it deals with Ruby objects, and ActiveRecord takes care of persisting those objects in the database.&lt;/li&gt;
	&lt;li&gt;Rails provides many classes and methods that facilitate common tasks in web applications, such as processing data from forms and validating data before writing it to the database.&lt;/li&gt;
	&lt;li&gt;Rails &lt;a href="/topic/show/10-views"&gt;views&lt;/a&gt; are created by a templating system that automatically composites each web page from a &lt;a href="/topic/show/114-layouts"&gt;layout&lt;/a&gt;, which typically provides the overall structure for the page, a template that defines the unique content of the page, and a special type of template, called a partial, for elements that are used in multiple places.&lt;/li&gt;
	&lt;li&gt;The Rails templating system allows you to mix &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; and Ruby code, and it provides a rich set of helpers to simplify the generation of &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; and JavaScript code. There&amp;#8217;s also a special type of template for producing &lt;span class="caps"&gt;&lt;span class="caps"&gt;XML&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
	&lt;li&gt;There&amp;#8217;s also support for &lt;a href="/topic/show/85-caching"&gt;caching&lt;/a&gt; pages and parts of pages to increase performance.&lt;/li&gt;
	&lt;li&gt;&lt;a href="/topic/show/91-rjs"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;RJS&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; (Ruby JavaScript) templates allow you to write Ruby code that the Rails framework translates to JavaScript for execution in the browser. This is a powerful facility for easily creating sophisticated Ajax interactions.&lt;/li&gt;
	&lt;li&gt;Rails migrations enable you to define your database schema with Ruby code, and to easily migrate from one version of the schema to another.&lt;/li&gt;
	&lt;li&gt;&lt;a href="/topic/show/56-testing"&gt;Testing&lt;/a&gt; is built into Rails, streamlining the process of writing and running automated tests for your application at various levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, as you can see, there&amp;#8217;s a lot to Rails. And there&amp;#8217;s more &amp;#8212; the Rails ecosystem includes a number of tools and extension methods:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Generators are special Rails methods that automate the creation of models, controllers, and so forth.&lt;/li&gt;
	&lt;li&gt;&lt;a href="/topic/show/79-scaffolds"&gt;Scaffolds&lt;/a&gt; are a kind of generator that automates the creation of a basic set of integrated functionality. Most often this is used to support the Create/Read/Update/Delete (&lt;span class="caps"&gt;&lt;span class="caps"&gt;CRUD&lt;/span&gt;&lt;/span&gt;) views and controller actions for a given model, but scaffolds are available for other features such as &lt;a href="/topic/show/105-rest"&gt;RESTful&lt;/a&gt; interfaces.&lt;/li&gt;
	&lt;li&gt;&lt;a href="/topic/show/77-gems"&gt;Gems&lt;/a&gt; are packages of Ruby code that are easily shared.&lt;/li&gt;
	&lt;li&gt;Rails &lt;a href="/topic/show/71-plugins"&gt;plugins&lt;/a&gt; are like gems but are installed directly into a particular Rails application.&lt;/li&gt;
	&lt;li&gt;Two &lt;a href="/topic/show/34-javascript"&gt;JavaScript&lt;/a&gt; frameworks are directly supported by Rails: &lt;a href="/topic/show/38-prototype"&gt;Prototype&lt;/a&gt;, which extends the JavaScript language, abstracts away browser differences, and makes many common tasks simpler; and &lt;a href="/topic/show/39-scriptaculous"&gt;Scriptaculous&lt;/a&gt;, which is a visual effects library.&lt;/li&gt;
	&lt;li&gt;RDoc and RI are Ruby tools for creating and viewing program documentation.&lt;/li&gt;
	&lt;li&gt;The Rails Console provides a command-line environment for interacting directly with your application.&lt;/li&gt;
	&lt;li&gt;&lt;a href="/topic/show/212-rake"&gt;Rake&lt;/a&gt; is an automation tool for performing common tasks in developing Rails applications, such as migrating from one database schema version to another.&lt;/li&gt;
	&lt;li&gt;Capistrano is an automation tool for &lt;a href="/topic/show/44-rails-deployment"&gt;deploying applications&lt;/a&gt;. It automates the process of publishing new versions to a production or staging server, and it also allows you to perform many server tasks without having to explicitly log in to the server and issue shell commands.&lt;/li&gt;
	&lt;li&gt;Mongrel is an application server that is widely used to run Rails applications. Typically an &lt;a href="/topic/show/90-http-servers"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; server&lt;/a&gt;, such as Apache or Nginx, serves up static content and cached pages, while requests that require Rails processing are sent to Mongrel.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Now What?&lt;/h2&gt;
&lt;p&gt;That wraps up our whirlwind tour of what Rails is and why it&amp;#8217;s worth learning. Follow the links in the article to learn more about each of the topics. And for an easy way to begin learning, sign up for our &lt;a href="/course"&gt;free online course in Ruby on Rails&lt;/a&gt;.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Y8REbrP-zAY:UU2oEhLlKto:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Y8REbrP-zAY:UU2oEhLlKto:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Y8REbrP-zAY:UU2oEhLlKto:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=Y8REbrP-zAY:UU2oEhLlKto:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/Y8REbrP-zAY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6400-understanding-ruby-on-rails</feedburner:origLink></entry>
  <entry>
    <title>Silicon Valley Ruby Conference</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/dSjMag0IbTE/6506-silicon-valley-ruby-conference" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6506-silicon-valley-ruby-conference</id>
    <updated>2008-04-21T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Last week's Silicon Valley Ruby Conference was perhaps the year's largest local gathering of Ruby enthusiasts, with 130 attendees. Here we present notes from a few of the presentations, on topics including Pivotal's Desert framework, IronRuby, Rubinius and Merb, and IBM's use of Rails.</summary>
    <content type="html">
&lt;p&gt;Last week&amp;#8217;s Silicon Valley Ruby Conference was perhaps the year&amp;#8217;s largest local gathering of Ruby enthusiasts, with 130 attendees. Although not in the same league as the big-time RailsConf and RubyConf events, it was nonetheless a worthwhile couple of days.&lt;/p&gt;
&lt;p&gt;In this article, we present a few tidbits from various talks at the conference. We&amp;#8217;ve also posted separate articles from two talks:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.buildingwebapps.com/articles/24-tim-bray-ruby-is-the-leading"&gt;Tim Bray: Ruby is the Leading Language for Web Applications&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.buildingwebapps.com/articles/23-selling-friends-scaling-a-high-traffic-rails"&gt;Selling Friends: Scaling a High-Traffic Rails Application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Desert Framework&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://pivots.pivotallabs.com/users/parker/blog"&gt;Parker Thompson&lt;/a&gt; from &lt;a href="http://pivotallabs.com/"&gt;Pivotal Labs&lt;/a&gt; talked about the &lt;a href="http://rubyforge.org/projects/pivotalrb/"&gt;Desert component framework&lt;/a&gt;. This open-source framework is a gem that Pivotal Labs uses to easily modularize their application components and quickly assemble them to create new applications.&lt;/p&gt;
&lt;div style='float:left; width:210px'&gt;
&lt;p&gt;&lt;img src="/parker.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The Desert framework allows a component to provide models, migrations, routes, controllers, views, and even plugins. It includes a modification to the Rails class loader, allowing code to define a class in multiple places, yielding the sum of all of them. Components are templating language agnostic. The framework deals with dependencies between plugins and load order &amp;#8212; something Parker noted should be in Rails.&lt;/p&gt;
&lt;p&gt;Pivotal has built about a dozen apps with the Desert framework and has done one full rewrite of the framework. While the framework itself is open source, Pivotal has not, unfortunately, open-sourced any of the components, which limits the immediate appeal. Pivotal may release some of the components in the future.&lt;/p&gt;
&lt;h2&gt;IronRuby&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.iunknown.com/"&gt;John Lam&lt;/a&gt; talked about the &lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; project. He is one of two people at Microsoft working on IronRuby. They&amp;#8217;ve been working on it for 14 months and are getting &amp;#8220;relatively close to running real ruby programs&amp;#8221;; John characterized it as &amp;#8220;about halfway done.&amp;#8221; IronRuby runs on top of the &lt;a href="http://blogs.msdn.com/hugunin/archive/2007/04/30/a-dynamic-language-runtime-dlr.aspx"&gt;Dynamic Language Runtime&lt;/a&gt; (&lt;span class="caps"&gt;&lt;span class="caps"&gt;DLR&lt;/span&gt;&lt;/span&gt;), which in turn runs on the Common Language Runtime (&lt;span class="caps"&gt;&lt;span class="caps"&gt;CLR&lt;/span&gt;&lt;/span&gt;), just as &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt;IronPython&lt;/a&gt; does.&lt;/p&gt;
&lt;p&gt;The runtime environment is part of &lt;a href="http://www.microsoft.com/silverlight/"&gt;Silverlight&lt;/a&gt;, which is a 4M download, on top of 1M download for video playing, plus 1.5M for &lt;span class="caps"&gt;&lt;span class="caps"&gt;DLR&lt;/span&gt;&lt;/span&gt; and Ruby. When this technology is ready, you could run a Rails view on the client instead of on the server. You could run Ruby &amp;#8220;on both sides of the wire&amp;#8221; and access .&lt;span class="caps"&gt;&lt;span class="caps"&gt;NET&lt;/span&gt;&lt;/span&gt; routines from Ruby. Because IronRuby lives in the Silverlight security model, it allows Ruby code to run from within the browser without needing to have its own security model.&lt;/p&gt;
&lt;p&gt;IronRuby is being released under the &lt;a href="http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx"&gt;Microsoft Public License&lt;/a&gt;,  Microsoft&amp;#8217;s open-source license.&lt;/p&gt;
&lt;h2&gt;Rubinius and Merb&lt;/h2&gt;
&lt;p&gt;Tom Morini from &lt;a href="http://engineyard.com"&gt;Engine Yard&lt;/a&gt; talked about the state of Ruby and the Rubinius project. Tom noted that the growth in Ruby jobs is quite dramatic:&lt;/p&gt;
&lt;div style="width:540px"&gt;
&lt;p&gt;&lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java&amp;relative=1&amp;relative=1" title="ruby, java Job Trends"&gt;&lt;br /&gt;
&lt;img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=ruby%2C+java&amp;relative=1" border="0" alt="ruby, java Job Trends graph"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%"&gt;&lt;tr&gt;&lt;br /&gt;
&lt;td&gt;&lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java&amp;relative=1&amp;relative=1"&gt;ruby, java Job Trends&lt;/a&gt;&lt;/td&gt;
&lt;td align="right"&gt;&lt;a href="http://www.indeed.com/jobs?q=ruby"&gt;ruby jobs&lt;/a&gt; &amp;#8211; &lt;a href="http://www.indeed.com/jobs?q=java"&gt;java jobs&lt;/a&gt;&lt;/td&gt;&lt;/p&gt;
&lt;p&gt;&lt;/tr&gt;&lt;p&gt;&lt;/table&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;However, this is on a relative scale. On an absolute scale, it&amp;#8217;s clear that there are still vastly more Java jobs:&lt;/p&gt;
&lt;div style="width:540px"&gt;
&lt;p&gt;&lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java" title="ruby, java Job Trends"&gt;&lt;br /&gt;
&lt;img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=ruby%2C+java" border="0" alt="ruby, java Job Trends graph"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%"&gt;&lt;tr&gt;&lt;br /&gt;
&lt;td&gt;&lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+java"&gt;ruby, java Job Trends&lt;/a&gt;&lt;/td&gt;
&lt;td align="right"&gt;&lt;a href="http://www.indeed.com/jobs?q=ruby"&gt;ruby jobs&lt;/a&gt; &amp;#8211; &lt;a href="http://www.indeed.com/jobs?q=java"&gt;java jobs&lt;/a&gt;&lt;/td&gt;&lt;/p&gt;
&lt;p&gt;&lt;/tr&gt;&lt;p&gt;&lt;/table&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Nevertheless, it is compelling that the number of Java jobs is stagnant, while Ruby jobs are increasing steadily.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; is a next-generation virtual machine for Ruby that is written entirely in Ruby. The project is now backed by Engine Yard, which hired project creator &lt;a href="http://blog.fallingsnow.net/"&gt;Evan Phoenix&lt;/a&gt; and four other top Ruby programmers to work on it. Tom said they hope to have a demo running Rails by RailsConf in May, and to have a 1.0 release this summer.&lt;/p&gt;
&lt;p&gt;There are 136 committers to date to Rubinius, making it the largest Ruby interpreter project by that measure; there are only 53 on the Matz Ruby Interpreter (&lt;span class="caps"&gt;&lt;span class="caps"&gt;MRI&lt;/span&gt;&lt;/span&gt;), 22 on Jruby, and 10 on IronRuby.&lt;/p&gt;
&lt;p&gt;The RubySpecs project, which is an RSpec test suite for the Ruby language being built for Rubinius, is becoming the definition of the Ruby language, which has no formal definition. There are currently 22,664 expectations in the tests.&lt;/p&gt;
&lt;p&gt;Matz is participating in &lt;a href="http://www.novemberain.com/2008/4/22/first-ruby-design-meeting-notes"&gt;monthly meetings with other Ruby implementors&lt;/a&gt;, which should help ensure that Ruby compatibility remains high even as the number of execution environments proliferates.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://merbivore.com/"&gt;Merb&lt;/a&gt;, which is also being backed by Engine Yard, is a Rails-like framework that was originally designed to solve file upload problems with Rails applications. It is steadily increasing in capability. Sony is writing &lt;a href="http://railswork.com/jobs/185-sr-on-line-engineer"&gt;backends for &lt;span class="caps"&gt;&lt;span class="caps"&gt;PSP&lt;/span&gt;&lt;/span&gt; and PlayStation 3 games&lt;/a&gt; in Merb, and music site &lt;a href="http://mog.com"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;MOG&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; is being rewritten in Merb. The 1.0 release of Merb is planned for this summer.&lt;/p&gt;
&lt;h2&gt;Rails at &lt;span class="caps"&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&amp;#8217;s &lt;a href="http://jhingran.typepad.com/"&gt;Anant Jhingran&lt;/a&gt; and &lt;a href="http://blog.juliankamil.com/"&gt;Julian Kamil&lt;/a&gt; talked about using Rails in enterprise environments. It may come a surprise to some that &lt;span class="caps"&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&lt;/span&gt; has created a number of web applications for clients using Rails. One example is the site for the &lt;a href="http://nmaahc.si.edu/"&gt;National Museum of African American History and Culture&lt;/a&gt;, which has launched as a virtual museum while the physical museum is being constructed. The site was created by a team from from &lt;a href="http://ibm.com/services/innovation/dc"&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&amp;#8217;s Innovation Center in Washington, DC&lt;/a&gt;.&lt;/p&gt;
&lt;div style='float:left; width: 310px'&gt;
&lt;p&gt;&lt;img src="/ibm.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p style='font-size: 10px; margin-top:0'&gt;Anant Jhingran (left) and Michael &amp;#8216;Max&amp;#8217; Maximilien&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The speakers noted that while Rails is not ready to replace core enterprise functions, it can be used very effectively to manage web services and create mashups that draw on other enterprise systems. Julian calls this &amp;#8220;penetration from the skin,&amp;#8221; rather than attacking the core. He showed that he has Rails running on an &lt;span class="caps"&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&lt;/span&gt; S/390 mainframe, and Anant talked about using &lt;span class="caps"&gt;IBM&lt;/span&gt;&amp;#8217;s DB2 database with Rails.&lt;/p&gt;
&lt;p&gt;One barrier is that some customer contracts prohibit the use of open-source software because they want everything to be fully supported. This is a customer education issue, rather than a technology challenge. In terms of Rails itself, the highly prescriptive nature of Rails (such as the lack of support for natural database keys) is a challenge when working with core enterprise functions.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.maximilien.com"&gt;Michael &amp;#8216;Max&amp;#8217; Maximilien&lt;/a&gt; from &lt;span class="caps"&gt;IBM&lt;/span&gt;&amp;#8217;s San Jose research lab showed his &lt;a href="http://services.alphaworks.ibm.com/isc/"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;/span&gt; for mashups&lt;/a&gt;, which allows mashups to be easily defined in a Ruby-based &lt;span class="caps"&gt;&lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;/span&gt; and then automatically creates a Rails application that implements them.&lt;/p&gt;
&lt;h2&gt;More Presentations and Videos&lt;/h2&gt;
&lt;p&gt;These notes reflect only about half of the presentations; see the &lt;a href="http://sdforum.org/ruby"&gt;SD Forum&lt;/a&gt; site for links to other presentations. They will also be publishing video recordings of the presentations.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=dSjMag0IbTE:s6AyujpYKTM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=dSjMag0IbTE:s6AyujpYKTM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=dSjMag0IbTE:s6AyujpYKTM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=dSjMag0IbTE:s6AyujpYKTM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/dSjMag0IbTE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6506-silicon-valley-ruby-conference</feedburner:origLink></entry>
  <entry>
    <title>Using SSL in Rails Applications</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/IibX9nCMTXY/6401-using-ssl-in-rails-applications" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6401-using-ssl-in-rails-applications</id>
    <updated>2008-04-05T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>If your web application manages any private information, you should be using SSL (https://) for pages where that information is entered or displayed. Fortunately, implementing SSL isn't too hard, once you know what you need to do.</summary>
    <content type="html">
&lt;p&gt;If your web application manages any private information, you should be using &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; (https://) for those parts of the application. Any data sent over a plain http connection can be &amp;#8220;sniffed&amp;#8221; by any &lt;span class="caps"&gt;&lt;span class="caps"&gt;ISP&lt;/span&gt;&lt;/span&gt; along the route that the packets take if you aren&amp;#8217;t using &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, implementing &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; isn&amp;#8217;t too hard, once you know what you need to do. This article will talk you through the process. These are the steps we&amp;#8217;ll go through:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Create your private key&lt;/li&gt;
	&lt;li&gt;Create your certificate signing request&lt;/li&gt;
	&lt;li&gt;Get your certificate&lt;/li&gt;
	&lt;li&gt;Configure your web server&lt;/li&gt;
	&lt;li&gt;Set up your Rails application&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Creating your private key&lt;/h2&gt;
&lt;p&gt;The first thing you need is a private key, with which your certificate will be encrypted, and which will be used to encrypt your &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; pages before they are sent. You make the private key yourself. Assuming your server has openSSL installed, enter the following command in an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; shell:&lt;/p&gt;
&lt;pre&gt;
openssl genrsa -out domainname.key 1024
&lt;/pre&gt;
&lt;p&gt;This creates your private key in the file domainname.key (you should substitute your domain name for domainname, of course, although the name doesn&amp;#8217;t really matter). This key is unprotected, so you should ensure that this file is readable only by the root user:&lt;/p&gt;
&lt;pre&gt;
chmod 600 domainname.key
&lt;/pre&gt;
&lt;p&gt;Alternatively, you can create your key in an encrypted form that will require you to specify a passphrase when creating the key, and to enter that passphrase to access the key:&lt;/p&gt;
&lt;pre&gt;
openssl genrsa -des3 -out domainname.key 1024
&lt;/pre&gt;
&lt;p&gt;This makes your key more secure, but it has a big downside: once you&amp;#8217;ve installed the key, you&amp;#8217;ll need to enter the passphrase any time the web server is rebooted. If you&amp;#8217;re not around and there&amp;#8217;s an emergency reboot of your server, your site will be down until someone can log in and enter the key.&lt;/p&gt;
&lt;p&gt;If you do encrypt your key, don&amp;#8217;t forget your passphrase! Without it, your key, and the certificate that uses it, will be worthless, and there&amp;#8217;s no way to recover it.&lt;/p&gt;
&lt;h2&gt;Creating your certificate signing request&lt;/h2&gt;
&lt;p&gt;Now that you have your private key, you can create the certificate signing request (&lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt;), which you&amp;#8217;ll need to get your certificate.&lt;/p&gt;
&lt;p&gt;In the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; shell on your server, create your &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt; as follows:&lt;/p&gt;
&lt;pre&gt;
openssl req -new -key domainname.key -out domainname.csr
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll be prompted to provide the name of the company, the country, city, and state, and some other information. The most critical piece of information here is the common name, which must exactly match the domain of the server on which the certificate will be used, including any subdomain. Note that www counts as a subdomain, so one certificate works either with www.domainname.com &lt;strong&gt;or&lt;/strong&gt; with domainname.com. You can also buy a &amp;#8220;wildcard&amp;#8221; certificate, which works with any subdomain, but they&amp;#8217;re much more expensive (at this writing, $199 vs. $19.99 at GoDaddy). (To make your site work with or without the www prefix, you should be redirecting accesses to one or the other, so you&amp;#8217;ll only need a certificate for one of them.)&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t enter any of the &amp;#8220;extra&amp;#8221; information that you&amp;#8217;ll be prompted for. In particular, don&amp;#8217;t enter a challenge phrase, or the certificate signing authority won&amp;#8217;t be able to read your request.&lt;/p&gt;
&lt;p&gt;The file domainname.csr will now contain a string of text, which you&amp;#8217;ll shortly be providing to your certificate authority. The file contents should look something like this:&lt;/p&gt;
&lt;pre&gt;
-----BEGIN CERTIFICATE REQUEST-----
MIIBxjCCAS8CAQAwgYUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTETMBEGA1UE
BxMKU2ViYXN0b3BvbDEXMBUGA1UEChMOTXkgV2ViIENvbXBhbnkxGzAZBgNVBAMT
End3dy5kb21haW5uYW1lLmNvbTEeMBwGCSqGSIb3DQEJARYPbWVAbXlkb21haW4u
Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpyw/LtDRQo/MCtDlckqLz
Cghnod7OFjcGXqprRW15Vn8bTB4v2L29lx2n+U1uK9jWCO/bZFUzVDZ/ESWhCRN8
roqbNuCxBdAzpX2M92RPcZWPeK+cRaJ7kafn5B8kyTXHenYWBAu/epy1NG7fagoO
qV4nqmCv0EwTkeWm9uShjQIDAQABoAAwDQYJKoZIhvcNAQEEBQADgYEAgXpQ6E0/
SyX7r25VI1EoLz2lRBX6tkqhOoBlVAPzDVN88todMaLQlbCz0VXKP9eS78cZe8kJ
7jI+Ujmio7GQ8zFLwpMCXzGCkpri30wO4hsK1lfvC/ScPTEayISECUNlTlRbRztW
W7AH4Z67d47E1hctoitbXSCbQVOfGavm1mA=
-----END CERTIFICATE REQUEST-----
&lt;/pre&gt;
&lt;h2&gt;Getting your certificate&lt;/h2&gt;
&lt;p&gt;Now you need to choose where to get your certificate, and what level of verification to pay for. To understand the choices, keep in mind that an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; certificate provides two separate functions:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;It certifies, to varying degrees, the identity of the person or business that controls the web site.&lt;/li&gt;
	&lt;li&gt;It provides the public and private keys for encrypting communications with the site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can get certificates at prices ranging from less than $20 to more than $1500, and they all provide the same encryption. The only difference is the degree to which they verify that you are who you say you are, and the seal that they give you to display on your web site. For more on certificates and certificate authorities, see &lt;a href="http://www.mslater.com/2007/5/9/implementing-ssl"&gt;Implementing &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;. Or, if you don&amp;#8217;t care about all the fancy stuff (which, for the most part, provides little value) just go to &lt;a href="http://www.godaddy.com/ssl"&gt;GoDaddy&lt;/a&gt; and get your $19.99 Turbo &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; certificate.&lt;/p&gt;
&lt;p&gt;The workflow will vary depending on your certificate authority; I&amp;#8217;ll describe how it works at GoDaddy.&lt;/p&gt;
&lt;p&gt;When you purchase your certificate, you get a credit that is good for one certificate. You then log into the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; Certificate part of the site and use the credit to request a certificate. The web form provides a form field into which you paste the text from the &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt; you generated in the previous step.&lt;/p&gt;
&lt;p&gt;When you submit the &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt;, the certificate authority will email the administrative contact for the domain to ask if they want to approve the request. This is how they verify that the certificate belongs to the domain. If you purchase a more expensive certificate, at this point they&amp;#8217;ll perform additional verification steps to ensure that the certificate belongs to who it says it belongs it.&lt;/p&gt;
&lt;p&gt;Once the &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt; is approved, you&amp;#8217;ll get an email with a link to download a zip file that contains the two certificate files you need to install on your server. One is your certificate, and will be named something like &amp;#8220;domainname.com.crt.&amp;#8221; The other is the &lt;em&gt;intermediate bundle&lt;/em&gt; certificate that establishes the chain that connects your certificate to the signing authority. In GoDaddy&amp;#8217;s case, this is gd_intermediate_bundle.crt.&lt;/p&gt;
&lt;p&gt;Now is a good time to make a backup of these files. The intermediate bundle is a standard file that you can usually get again, and you can request that your certificate authority re-issue your certificate file. But if you lose the key file, your certificate is worthless, and you&amp;#8217;ll have to purchase another one.&lt;/p&gt;
&lt;h2&gt;Configuring your web server&lt;/h2&gt;
&lt;p&gt;Now you need to configure your web server for &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;. Just how this is done depends on what server your using, its version, and how it was installed and configured. I&amp;#8217;ll describe how it works for a typical Apache 2.x configuration; you may need to adjust this for your situation.&lt;/p&gt;
&lt;p&gt;You should already have virtual host definition, either in your httpd.conf file or in an application-specific configuration file that is included into the main httpd.conf by reference. There are two kinds virtual host definitions: name-based, and IP address based. You can&amp;#8217;t use name-based virtual hosts with &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, so you&amp;#8217;ll need to have a dedicated IP address for the site that is using &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;. If you only have one IP address for your server, you&amp;#8217;ll only be able to have one application. If you want to host multiple applications, your host should be able to provide you with multiple IP addresses.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll need two virtual host blocks, one for the non-&lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; parts of the site, and another for the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; parts. The basic configuration should look something like this:&lt;/p&gt;
&lt;pre&gt;
&amp;amp;lt;VirtualHost 123.456.789.123:80&amp;amp;gt;

  Include conf/apps/domainname.conf.common

&amp;amp;lt;/VirtualHost&amp;amp;gt;

&amp;amp;lt;VirtualHost 123.456.789.123:443&amp;amp;gt;

  Include conf/apps/domainname.conf.common

  # SSL Engine Switch
  SSLEngine on

  # SSL Cipher Suite:
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

  # Server Certificate
  SSLCertificateFile /etc/httpd/conf/ssl.crt/domainname.com.crt

  # Server Private Key
  SSLCertificateKeyFile /etc/httpd/conf/ssl.key/domainname.key

  # Server Intermediate Bundle
  SSLCertificateChainFile /etc/httpd/conf/ssl.crt/gd_intermediate_bundle.crt

  # Set header to indentify https requests for Mongrel
  RequestHeader set X-Forwarded-Proto "https"

  BrowserMatch ".*MSIE.*" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
  
  CustomLog logs/domainname.com-ssl_log \
    "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

&amp;amp;lt;/VirtualHost&amp;amp;gt;
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s walk through this. The first virtual host block is essentially the same as what you&amp;#8217;d have without &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, except that you have to specify an IP address (123.456.789.123 in this example). I&amp;#8217;ve put all the configuration that would normally go here, to set up the proxy to Mongrel and any mod_rewrite rules, into an include file, domainname.conf.common, which is not shown here. Doing so allows the same commands to be reused in the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; block.&lt;/p&gt;
&lt;p&gt;The second virtual host block defines the same IP address, but this time for port 443, which is the standard &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; port. First we include all the common configuration code to handle mongrel and so forth. Then, finally, comes the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; configuration directives. We need to turn on the &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; engine, specify the encryption to be used, and point to the three files we generated earlier: the key, the certificate, and the intermediate bundle. (The &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSR&lt;/span&gt;&lt;/span&gt; isn&amp;#8217;t needed once the certificate has been generated.) In this example, I&amp;#8217;ve shown them going in subdirectories of conf, but you can put them anywhere, as long as these pointers match the location.&lt;/p&gt;
&lt;p&gt;Next, we set the request header to tell mongrel when there is an https connection. Don&amp;#8217;t leave this out, or you&amp;#8217;ll have no end of confusing problems in your Rails code!&lt;/p&gt;
&lt;p&gt;Finally, there&amp;#8217;s a bit of config to keep Internet Explorer happy, and a custom log definition to log &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; accesses to a separate log file (this last bit is entirely optional).&lt;/p&gt;
&lt;p&gt;To test all this, enter&lt;/p&gt;
&lt;pre&gt;
apachectl configtest
&lt;/pre&gt;
&lt;p&gt;in an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt;&lt;/span&gt; shell. This will check your config files for syntax errors without actually rebooting the server, so in case there&amp;#8217;s a problem you don&amp;#8217;t leave the server disabled while you sort out any errors.&lt;/p&gt;
&lt;p&gt;At last, you can now reboot Apache (sudo service httpd restart), and if everything is correct, you&amp;#8217;ll have an operating &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; server.&lt;/p&gt;
&lt;h2&gt;Tell your Rails app where to use &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;With the above setup done, you should be able to browse to any page in your application using either http:// or https://. You&amp;#8217;ll probably want to leave parts of the site unsecured, since &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; pages put extra load on the server, so you need a way to indicate which pages require &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, and which don&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;The ssl_requirement plugin, written by &lt;span class="caps"&gt;&lt;span class="caps"&gt;DHH&lt;/span&gt;&lt;/span&gt; himself, makes this simple. Install the plugin:&lt;/p&gt;
&lt;pre&gt;
script/plugin install ssl_requirement
&lt;/pre&gt;
&lt;p&gt;And then include it at the top of your application.rb file, which effectively includes it in every controller:&lt;/p&gt;
&lt;pre&gt;
include SslRequirement
&lt;/pre&gt;
&lt;p&gt;Now all you need to do is specify, at the top of each controller, which controller actions require &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;pre&gt;
ssl_required  :login, :account, :payment, :cart
&lt;/pre&gt;
&lt;p&gt;Be sure to include in this list any create or update actions that process form data from &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; pages. The magic of this is that you don&amp;#8217;t need to change any links; any access to an action that requires &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; will automatically redirect to https://. If anyone tries to access a page that is supposed to be secure with an http:// link, they&amp;#8217;ll be redirected.&lt;/p&gt;
&lt;p&gt;You can also provide an &lt;code&gt;ssl_allowed&lt;/code&gt; declaration if there are actions that you want to be able to access either way. Such actions won&amp;#8217;t redirect to https:// but if that protocol is explicitly specified in a link, it will work.&lt;/p&gt;
&lt;h2&gt;Check your Ajax actions&lt;/h2&gt;
&lt;p&gt;For the most part, that&amp;#8217;s all there is to it on the Rails side. There&amp;#8217;s just one more thing that may require your attention: actions that service Ajax requests.&lt;/p&gt;
&lt;p&gt;On any page accessed with &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, all Ajax requests must use &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, or they will fail. To make this happen, all you need to do is include the names of the actions that service the requests in your &lt;code&gt;ssl_required&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;In some cases, you may have Ajax actions that have no code in the controller, but are just rendering &lt;span class="caps"&gt;&lt;span class="caps"&gt;RJS&lt;/span&gt;&lt;/span&gt; templates or other views. For these actions, you&amp;#8217;ll need to add an empty action definition block in the controller, and add the action name to the &lt;code&gt;ssl_required&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;One obscure case is the text_field_with_auto_complete helper. If you&amp;#8217;re using this in your view, you&amp;#8217;re probably also using the &lt;code&gt;auto_complete_for :model :field&lt;/code&gt; shortcut in your controller. This automatically produces an action to respond to the autocomplete requests. But since the action isn&amp;#8217;t explicitly defined, how do you tell it to require &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;? You just need to know what the automatically created action is named, which is &lt;code&gt;auto_complete_for_model_field&lt;/code&gt;. Just substitute the names of your model and field, and add this action name to your &lt;code&gt;ssl_required&lt;/code&gt; statement.&lt;/p&gt;
&lt;h2&gt;Check for mixed content&lt;/h2&gt;
&lt;p&gt;One last thing to watch out for is mixed content. If you&amp;#8217;re testing in Firefox, you won&amp;#8217;t notice it, but in IE, users will get a security warning if an &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; page accesses any non-secure content. You don&amp;#8217;t have to worry about links to images and so forth, as long as they&amp;#8217;ve been written as paths without the full domain name; those will automatically use the protocol of the main page. But if you have any full links, you&amp;#8217;ll need to make sure they are written as &amp;#8220;https://&amp;#8221; on any &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; page.&lt;/p&gt;
&lt;p&gt;One case where this problem can sneak in is with JavaScript snippets for services such as Google analytics. If you have a Google analytics link on your page, change it from &amp;#8220;http://www.google-analytics.com/urchin.js&amp;#8221; to &amp;#8220;&lt;strong&gt;https://ssl.&lt;/strong&gt;google-analytics.com/urchin.js&amp;#8221;. (Google has now change its analytics code so this isn&amp;#8217;t necessary if you&amp;#8217;re using their current code.) This will work fine on all pages, whether they use &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt; or not, and it will keep the analytics link from triggering the mixed content warning.&lt;/p&gt;
&lt;h2&gt;Now you have &lt;span class="caps"&gt;&lt;span class="caps"&gt;SSL&lt;/span&gt;&lt;/span&gt;, but &amp;#8230;&lt;/h2&gt;
&lt;p&gt;Now your site can send pages in encrypted form, so they can&amp;#8217;t be snooped on by prying eyes along the path between your server and your user&amp;#8217;s computer. And the user can examine the certificate to see to whom it was granted, and know that the browser would warn them if the domain name didn&amp;#8217;t match.&lt;/p&gt;
&lt;p&gt;Of course, there&amp;#8217;s much more to keeping your users&amp;#8217; data secure. You need to ensure that all model requests are properly scoped, and for internal security, you need to make sure that confidential information isn&amp;#8217;t leaking out in your logs, exception reports, and backups.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=IibX9nCMTXY:uYedwhpfld0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=IibX9nCMTXY:uYedwhpfld0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=IibX9nCMTXY:uYedwhpfld0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=IibX9nCMTXY:uYedwhpfld0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/IibX9nCMTXY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6401-using-ssl-in-rails-applications</feedburner:origLink></entry>
  <entry>
    <title>Can Rails Scale? Absolutely!</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/3mNaBlVL_6U/6419-can-rails-scale-absolutely" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6419-can-rails-scale-absolutely</id>
    <updated>2008-04-05T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>There's a persistent chatter about scalability in discussions of Rails, especially among people who aren't actually using it. When we talk with people considering Rails for new sites, concerns about scalability often come up. In reality, while Rails is not the world's speediest framework, the supposed scalability issues are very unlikely to be a legitimate reason not to use Rails.</summary>
    <content type="html">
&lt;p&gt;There&amp;#8217;s a persistent chatter about scalability in discussions of Rails, especially among people who aren&amp;#8217;t actually using it. When we talk with people considering Rails for new sites, concerns about scalability often come up.&lt;/p&gt;
&lt;p&gt;In reality, while Rails is not the world&amp;#8217;s speediest framework, the supposed scalability issues are very unlikely to be a legitimate reason not to use Rails.&lt;/p&gt;
&lt;h2&gt;Where Are the Huge Rails Sites?&lt;/h2&gt;
&lt;p&gt;Some Rails critics attempt to reinforce scalability concerns by noting the lack of large, well-known web sites running Rails. After all, you won&amp;#8217;t find Rails behind the scenes at Yahoo, Google, eBay, MySpace, or Facebook.&lt;/p&gt;
&lt;p&gt;The major factor here, however, is not scalability, but age. It takes time for sites to become huge and well known, and Rails is one of the newest web frameworks. So of course it isn&amp;#8217;t at the heart of the relatively old, well-known web sites.&lt;/p&gt;
&lt;p&gt;It is worth noting, however, that there&amp;#8217;s strong interest in Ruby on Rails even at many of these large sites. eBay, Yahoo, and Amazon all have Rails projects under way. &lt;a href="http://joyent.com/developers/facebook/"&gt;Facebook is working with Joyent&lt;/a&gt; to support Rails apps on their platform. &lt;span class="caps"&gt;&lt;span class="caps"&gt;IBM&lt;/span&gt;&lt;/span&gt; Global Services is building Rails sites for clients. And Thoughtworks is using Rails for a large fraction of its enterprise development projects.&lt;/p&gt;
&lt;p&gt;So what are the largest Rails sites? The highest-traffic Rails site we&amp;#8217;re aware of is &lt;a href="http://yellowpages.com"&gt;yellowpages.com&lt;/a&gt;. This site isn&amp;#8217;t in the same league as Yahoo and Google, but it sees much higher traffic than anything you&amp;#8217;re likely to build (see figure). The second-highest-traffic site we&amp;#8217;ve been able to identify is &lt;a href="http://revolutionhealth.com"&gt;Revolution Health&lt;/a&gt;, headed by &lt;span class="caps"&gt;&lt;span class="caps"&gt;AOL&lt;/span&gt;&lt;/span&gt; founder Steve Case.&lt;/p&gt;
&lt;p&gt;&lt;a href='http://siteanalytics.compete.com/yellowpages.com+revolutionhealth.com+43things.com+odeo.com+twitter.com?metric=sess'&gt;&lt;img src='http://home.compete.com.edgesuite.net/yellowpages.com+revolutionhealth.com+43things.com+odeo.com+twitter.com_sess_460.png' /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note that this graph shows visits, so you can multiply the figures by perhaps 4 to 5 to get pageviews. That puts yellowpages.com around 100 million pageviews per month (Update: as you&amp;#8217;ll see in the comments below, developers at YellowPages.com report that they&amp;#8217;re serving around 170 million pages per month), and Revolution Health at around 30 million. Of course, these are unconfirmed, third-party estimates, so they aren&amp;#8217;t precise, but they&amp;#8217;re probably in the ballpark.&lt;/p&gt;
&lt;p&gt;The oldest Rails site of all, &lt;a href="http://basecamphq.com"&gt;Basecamp&lt;/a&gt;, is unfortunately hard to measure because its users are spread across many domains and subdomains. Basecamp claims over 1 million users, but it&amp;#8217;s impossible to know what that really means.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt; is perhaps one of the highest-traffic Rails applications, in terms of transactions per second, but because most of those accesses are not web page views they don&amp;#8217;t show up in public measurement metrics. Twitter had some well-publicized problems scaling their Rails infrastructure, but in fact these problems were overcome with a couple months work. Somehow this fact generated less publicity. Twitter remains on Rails.&lt;/p&gt;
&lt;p&gt;Some other well-known Rails sites include &lt;span class="caps"&gt;CNET&lt;/span&gt;&amp;#8217;s &lt;a href="http://chowhound.com"&gt;Chowhound&lt;/a&gt;, &lt;a href="http://43things.com"&gt;43things&lt;/a&gt;, &lt;a href="http://spock.com"&gt;Spock&lt;/a&gt;, and &lt;a href="http://penny-arcade.com"&gt;Penny Arcade&lt;/a&gt;. At least in how they show up on measurement services such as &lt;a href="http://www.alexa.com"&gt;Alexa&lt;/a&gt; and &lt;a href="http://compete.com"&gt;Compete.com&lt;/a&gt;, however, their traffic isn&amp;#8217;t close to that of yellowpages.com or Revolution Health.&lt;/p&gt;
&lt;p&gt;So, for now, yellowpages.com seems like the best proof point. If you have any data to add about these or any other sites, please &lt;a href="/contact"&gt;let us know&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Sources of Scaling Issues&lt;/h2&gt;
&lt;p&gt;Concerns about Rails scaling probably come, in part, from Ruby&amp;#8217;s reputation as a relatively slow language. No one will argue that Ruby is a speed demon. But it&amp;#8217;s also true that it is a very rare web application that comes anywhere close to being compute-bound. Database access and network delays are almost always the overwhelming factors. And in the coming year, we&amp;#8217;ll see &lt;a href="http://antoniocangiano.com/2007/02/19/ruby-implementations-shootout-ruby-vs-yarv-vs-jruby-vs-gardens-point-ruby-net-vs-rubinius-vs-cardinal/"&gt;major improvements in Ruby speed&lt;/a&gt;, as &lt;a href="http://www.ruby-lang.org/en/news/2007/12/25/ruby-1-9-0-released/"&gt;Ruby 1.9&lt;/a&gt; moves into widespread use and alternative execution environments, including &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; and &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;, reach production systems.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a lot of different things that can slow down a web application. Rails makes it easy to get your application running without worrying about any of the performance issues, and that&amp;#8217;s a good thing. If you ignore everything about performance tuning, you&amp;#8217;ll still have a working application, and from there you can tune. There&amp;#8217;s little point in tuning for performance before you have something that is successful for a small group of people. And if you focus on building an optimally scalable site and end up late to market as a result, you&amp;#8217;ll have achieved nothing.&lt;/p&gt;
&lt;p&gt;Rails provides a rich set of caching mechanisms that can dramatically increase the speed of most web applications. You can typically achieve dramatic performance gains by applying page, action, and fragment caching. And for big sites, memcached is a popular solution. In many cases, these solutions largely take Rails out of the picture for the highest-traffic pages.&lt;/p&gt;
&lt;p&gt;Another common source of performance problems is slow database queries. The ease with which you can access your data without writing any &lt;span class="caps"&gt;&lt;span class="caps"&gt;SQL&lt;/span&gt;&lt;/span&gt; or thinking too much about how associations really work can lead to very inefficient queries. So the next step after implementing caching is to look for queries that are being executed in loops and could be replaced with a single query. A simple change can sometimes yield an order-of-magnitude speedup.&lt;/p&gt;
&lt;p&gt;The next step is to look for individual queries that are slow. Often, data can be cached, using memcached or other solutions, eliminating queries entirely. And denormalizing the data can yield huge gains.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a variety of tools available to help you do so. You may need to add databases indexes, or add some :include clauses, or otherwise refactor your queries or your data. These are problems that apply to all frameworks and programming languages. Rails just makes it easier to ignore all these issues if your application isn&amp;#8217;t performance limited &amp;#8212; which is probably the case for 99.9% of all web applications.&lt;/p&gt;
&lt;h2&gt;Scaling the Hardware&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;ve done all this and you&amp;#8217;re down to a fundamental database performance bottleneck, you&amp;#8217;re neither better nor worse off with Rails than with any other web framework. All the usual solutions, such as adding mirrored read-only database servers, can be applied just as well to Rails apps as to those built with to Java, or &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt;, or whatever.&lt;/p&gt;
&lt;p&gt;When it comes to handling massive &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/span&gt; traffic, you can scale a Rails application horizontally just like any other by replicating your front-end web servers behind a load balancer. There&amp;#8217;s nothing about Rails that makes this more difficult than with any other technology.&lt;/p&gt;
&lt;p&gt;If you need to scale your Rails processing, you can add more Mongrels to your heart&amp;#8217;s content. (Mongrel is the most widely used Rails application server.) It is possible that the overhead of Rails means you&amp;#8217;ll need to devote more hardware to executing your application code, but as we discuss in the following section, the time savings of using Rails can pay for a lot of extra hardware.&lt;/p&gt;
&lt;p&gt;This kind of horizontal scaling is getting easier and less expensive all the time, as hardware costs drop and &amp;#8220;cloud computing&amp;#8221; solutions such as Amazon&amp;#8217;s EC2 become more widely used. &lt;a href="http://rightscale.com"&gt;RightScale&lt;/a&gt; can automate much of this scaling for Rails applications, even allowing you to quickly add more servers when demand peaks.&lt;/p&gt;
&lt;h2&gt;The Bottom Line&lt;/h2&gt;
&lt;p&gt;Scaling a web application to very high traffic levels is hard work, no matter what framework you use. Today, there is more experience in doing so with Java and &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; applications than with Rails applications. But every day there&amp;#8217;s more experience with high-traffic Rails sites, and the majority of the techniques used apply equally well to all frameworks and programming languages.&lt;/p&gt;
&lt;p&gt;Even if the overhead of Rails does increase your hardware requirements, it doesn&amp;#8217;t necessarily increase your total costs. Suppose the ease of Rails development means that you can do the same work with 4 developers that would require 5 with another technology. (Many teams will tell you that this is a gross understatement of the savings, but it&amp;#8217;s plenty to illustrate our point.)&lt;/p&gt;
&lt;p&gt;Eliminating that single developer from your team will save you somewhere between $100,000 and $250,000 per year, depending on how senior they are, how well you pay, and what your overhead is. But let&amp;#8217;s stick with the low end of the range. For $100,000 per year, you can get perhaps two-dozen high-end servers at a first-class hosting facility. That will get you quite a few more Mongrels.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re at Yahoo or Google looking at replacing your core infrastructure, then you&amp;#8217;d better look very carefully at scaling issues, and it might be worth using the most compute-efficient language to minimize that amount of hardware you need. But for nearly everyone else, all the concerns about Rails scalability are just noise. Don&amp;#8217;t let the &lt;span class="caps"&gt;&lt;span class="caps"&gt;FUD&lt;/span&gt;&lt;/span&gt; keep you from choosing the technology that will maximize the efficiency of your development team.&lt;/p&gt;
&lt;h2&gt;For Further Reading&lt;/h2&gt;
&lt;p&gt;See our &lt;a href="/topic/50-performance-tuning"&gt;Performance Tuning&lt;/a&gt; section for links to a variety of related resources.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.loudthinking.com/arc/000479.html"&gt;It&amp;#8217;s boring to scale with Ruby on Rails&lt;/a&gt;, a July 2005 article by David Heinemeier Hansson&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://poocs.net/2006/3/13/the-adventures-of-scaling-stage-1"&gt;The adventures of scaling, Stage 1&lt;/a&gt; by Patrick Lenz. He replaced a 50,000-line &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; site with a 5,000-line Rails site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to read up on the Twitter story, here&amp;#8217;s some references:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.radicalbehavior.com/5-question-interview-with-twitter-developer-alex-payne/"&gt;Interview with Twitter developer Alex Payne&lt;/a&gt;, which is what started the whole controversy&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.slideshare.net/al3x/scaling-twitter-railsconf-2007"&gt;Scaling Twitter&lt;/a&gt; presentation from RailsConf 2007&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://video.google.com/videoplay?docid=-7846959339830379167"&gt;Video of Scaling Twitter presentation&lt;/a&gt; given at the Silicon Valley Ruby Conference in 2007&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://glu.ttono.us/articles/2007/04/15/on-twitter-rails-and-community"&gt;Kevin Clark&amp;#8217;s article&lt;/a&gt; on the controversy around Twitter&amp;#8217;s scaling challenges&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Add to the Community Knowledge&lt;/h2&gt;
&lt;p&gt;If you have first-hand knowledge of traffic numbers at a large Rails site, or stories of scaling challenges and solutions, please add your comment here, or &lt;a href="/contact"&gt;send us an email&lt;/a&gt;.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=3mNaBlVL_6U:jFFe6H4__v0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=3mNaBlVL_6U:jFFe6H4__v0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=3mNaBlVL_6U:jFFe6H4__v0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=3mNaBlVL_6U:jFFe6H4__v0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/3mNaBlVL_6U" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6419-can-rails-scale-absolutely</feedburner:origLink></entry>
  <entry>
    <title>Jared Spool's Web App Summit</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/uKgvZ_lkal0/6502-jared-spool-s-web-app-summit" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6502-jared-spool-s-web-app-summit</id>
    <updated>2008-03-30T17:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Last week's Web App Summit, produced by Jared Spool's User Interface Engineering, had more than the usual quotient of quality talks. The presentations were almost entirely focused on user experience, with technology and business receiving only tangential attention, but there were enough user experience insights to make it a worthwhile couple of days.</summary>
    <content type="html">
&lt;p&gt;&lt;div style='float:left; padding: 0 10px 10px 0'&gt;&lt;br /&gt;
&lt;p&gt;&lt;img src="/webappsummit.png" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Last week&amp;#8217;s Web App Summit, produced by Jared Spool&amp;#8217;s User Interface Engineering, had more than the usual quotient of quality talks. The presentations were almost entirely focused on user experience, with technology and business receiving only tangential attention. Even the day titled &amp;#8220;Going from concept to code&amp;#8221; never really got to code, but there were enough user experience insights to make it a worthwhile couple of days.&lt;/p&gt;
&lt;p&gt;As one might expect of talks focused on user experience, most were quite visual and don&amp;#8217;t lend themselves to written summaries. What follows is a random sampling of tidbits that made it into my notes in an intelligible form.&lt;/p&gt;
&lt;h2&gt;Jared Spool, &lt;a href="http://uie.com"&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;UIE&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;ve ever seen one of Jared Spool&amp;#8217;s numerous conference presentations, you know that he is one of the industry&amp;#8217;s more entertaining and insightful speakers. His introduction followed a theme of &amp;#8220;web apps: where business rules meet user experience.&amp;#8221; The point, essentially, is that business rules sometimes need to be bent in the name of user experience. Jared advocates putting the user experience first, and using that to help define the business rules.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s often the little things that get customers excited. Jared calls these &amp;#8220;delighters.&amp;#8221; As the &lt;a href="http://en.wikipedia.org/wiki/Kano_model"&gt;Kano Model&lt;/a&gt; describes, customer needs can be divided into three categories:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Basic needs&lt;/strong&gt; are the things that everyone expects. If you don&amp;#8217;t meet them, it&amp;#8217;s a huge negative factor, but doing more than is expected has no benefit.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Performance needs&lt;/strong&gt; are attributes that vary over a wide range, and for which the customer values each improvement.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Excitement needs&lt;/strong&gt; are the &amp;#8220;wow&amp;#8221; features, which can produce lots of user satisfaction for a relatively low investment &amp;#8212; if you pick the right thing to implement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This theme came up repeatedly with other speakers: it&amp;#8217;s the little things that go beyond what&amp;#8217;s expected that give big boosts in user satisfaction.&lt;/p&gt;
&lt;h2&gt;Steve Mulder, &lt;a href="http://www.molecular.com/"&gt;Molecular&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Steve Mulder gave an excellent talk about user experience with rich internet applications. He started with the question &amp;#8220;To richify, or not to richify?&amp;#8221; His answer is that the designer should ask:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;What are common activities that could be easier?&lt;/li&gt;
	&lt;li&gt;Where do users want more flexibility or power?&lt;/li&gt;
	&lt;li&gt;Where are brand-immersive experiences valuable and effective?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As an example of an application in which an Ajax interaction significantly improves the user experience, Steve cited a single-screen checkout process. Products remain displayed on the left, while the form area on right is replaced, using Ajax, as the user goes through the checkout process.&lt;/p&gt;
&lt;p&gt;Steve recommended that designers &amp;#8220;prune with ferocity,&amp;#8221; overemphasize the core, underemphasize the cool stuff, and be obsessive about a consistent visual system for interactivity cues.&lt;/p&gt;
&lt;p&gt;Another interesting point was the clarification of two similar, but different, issues:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Findability&lt;/strong&gt; &amp;#8212; finding something you know is there&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Discoverability&lt;/strong&gt; &amp;#8212; finding something you don&amp;#8217;t know to look for&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Jeremy Keith, &lt;a href="http://clearleft.com"&gt;Clearleft&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Jeremy Keith gave an entertaining and largely visual talk which I&amp;#8217;m hard pressed to summarize. But here&amp;#8217;s a few tidbits:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A conceptual metaphor is using one idea to describe another&lt;/li&gt;
	&lt;li&gt;The web uses conceptual metaphors all the time &amp;#8212; move, navigate, browse, surf&lt;/li&gt;
	&lt;li&gt;In this metaphor, the user is a traveler, URLs are places&lt;/li&gt;
	&lt;li&gt;Interaction is different conceptual metaphor &amp;#8212; staying in one place and interacting with various things&lt;/li&gt;
	&lt;li&gt;Ajax enables interaction metaphor on the web &amp;#8212; user stays in one place&lt;/li&gt;
	&lt;li&gt;Ajax does not mean JavaScript &amp;#8212; asynchronous is what makes ajax special&lt;/li&gt;
	&lt;li&gt;Best Ajax definintion: communicating with the server without refreshing the whole page&lt;/li&gt;
	&lt;li&gt;Use progressive enhancement. First build the site without JavaScript. Then add JavaScript enhancements, but ensure that it continues to work without JavaScript.&lt;/li&gt;
	&lt;li&gt;Keep the business logic on the server&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bill Scott, &lt;a href="http://www.netflix.com"&gt;Netflix&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bill Scott, who directs the user experience team at Netflix and previously led the group at Yahoo that, among other things, created the Yahoo UI Pattern Library, gave an excellent talk on antipatterns: patterns to watch out for in your user experiences. His &lt;a href="http://billwscott.com/share/presentations/2008/webappsummit"&gt;presentation is available online&lt;/a&gt;, and while it doesn&amp;#8217;t quite stand alone without the narrative, it&amp;#8217;s still worth a look.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a few of the antipatterns:&lt;/p&gt;
&lt;h3&gt;Meandering way&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Need to move the mouse back and forth to complete a series of actions&lt;/li&gt;
	&lt;li&gt;Solution: reveal hidden tools on hover; avoid popup and page jitter; play on spatial memory&lt;/li&gt;
	&lt;li&gt;Anytime anything moves, it attracts the eye, so don&amp;#8217;t move things you don&amp;#8217;t mant to draw attention to&lt;/li&gt;
	&lt;li&gt;To analyze, draw arrows for each move required to complete a task&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pogo stick navigation&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Need to move back and forth between pages to accomplish a task&lt;/li&gt;
	&lt;li&gt;Solution: encapsulation of click stream into an overlay&lt;/li&gt;
	&lt;li&gt;Use in-context tools&lt;/li&gt;
	&lt;li&gt;Be careful with overlays to make the back button do the expected thing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Tiny targets&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Making key interaction targets too small&lt;/li&gt;
	&lt;li&gt;Apple site: video play button is 8 &amp;#215; 8 pixels, grey on grey, sometimes not near video (if large surround)&lt;/li&gt;
	&lt;li&gt;Use &amp;#8220;call to action&amp;#8221;-style buttons&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Hover and cover&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Pop-ups on hover can cover other important info&lt;/li&gt;
	&lt;li&gt;Hover is good for invitations but not for actions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Animation gone wild&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;You know what this means!&lt;/li&gt;
	&lt;li&gt;nasa.gov (animated menus and collapsing sections)&lt;/li&gt;
	&lt;li&gt;Carousel effect (amazon, others)&lt;/li&gt;
	&lt;li&gt;Tabs that animate change of content like a carousel&lt;/li&gt;
	&lt;li&gt;Just because you can, and it looks cool, doesn&amp;#8217;t mean that you &lt;em&gt;should&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Missed moments&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Not providing feedback throughout an interaction&lt;/li&gt;
	&lt;li&gt;Think &amp;#8220;interactive directions&amp;#8221; &amp;#8212; moment-by-moment directions are the key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bill is working on an interaction design book, which will include a section on antipatterns. It won&amp;#8217;t be out for some time, but it promises to be worth watching for.&lt;/p&gt;
&lt;h2&gt;Sean Kane, &lt;a href="http://getlisted.com"&gt;GetListed&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sean is currently a principal in the startup GetListed, an &amp;#8220;employment marketplace&amp;#8221; that he wasn&amp;#8217;t ready to talk about. His talk instead focused mostly on observations from Netflix, where he previously led the user experience group, and what start-ups can learn from big-company processes and techniques. (Sean actually spoke on the second day, but I&amp;#8217;m including him out of order to keep the Netflix thread going.)&lt;/p&gt;
&lt;p&gt;One of Sean&amp;#8217;s themes was the value of data. With Netflix&amp;#8217;s 7-million-plus user base, it has a great deal of data, and is able to use this data to evaluate alternative designs and features.&lt;/p&gt;
&lt;p&gt;One example of a data-driven decision: Netflix recently went from an 800-pixel-wide design to one that is 950 pixels wide, when data showed that only a very small part of the user base was using browser windows less than 1000 pixels across.&lt;/p&gt;
&lt;p&gt;Another interesting example was the way Netflix evaluated whether to add a &amp;#8220;multiple queues&amp;#8221; feature, so a single user could have multiple movie lists. They put a button labeled something like &amp;#8220;Add New Queue&amp;#8221; on the queue page, and if you clicked on it, the resulting page simply said &amp;#8220;Sorry, this feature is still in development.&amp;#8221; In the end, few people clicked on the button, and the feature was never developed.&lt;/p&gt;
&lt;p&gt;Yet another good case study was the way Netflix evaluated various user interfaces for showing customers a series of trailers that had been chosen for them by the recommendation engine. They implemented several different UIs, ranging from a very simple one that give the user no options but to advance from one trailer to the next, to a more complex UI that showed the user a series of box shots next to the video player, which the could click on to move from trailer to trailer.&lt;/p&gt;
&lt;p&gt;In qualitative testing, users liked the more capable UI. In quantitative testing, on the other hand, users of the more capable UI clicked on lots of movie boxes, but in the end they watched fewer trailers and performed fewer &amp;#8220;Add to Queue&amp;#8221; actions, which is what Netflix wants them to do. So the simpler UI turned out to be better in terms of meeting the business goal, even though it was not the one the designers liked best, the one that was most capable, nor the one that was favored in qualitative assessments.&lt;/p&gt;
&lt;p&gt;Sean emphasized the importance of agility. Netflix, even though it now a large company and runs a very high-traffic site, uses a two-week release cycle. This gives it more than 20 times a year to test new features and make incremental changes. Most changes aren&amp;#8217;t overtly noticed by users.&lt;/p&gt;
&lt;p&gt;(This is in striking contrast to one large photo sharing site with which I had some dealings with in the past, which updates their site &lt;em&gt;quarterly&lt;/em&gt;.)&lt;/p&gt;
&lt;h2&gt;Andrew DeVigal, &lt;a href="http://nytimes.com"&gt;New York Times&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Andrew DeVigal is the multimedia editor at the New York Times. You can see the wonderful presentations his team produces in the &lt;a href="http://www.nytimes.com/pages/multimedia/index.html"&gt;multimedia section&lt;/a&gt; of the Times site.&lt;/p&gt;
&lt;p&gt;Andrew&amp;#8217;s team is creating some of the best examples of using Flash to present information in a compelling way. I found it interesting that his team is not divided into journalists, designers, and Flash coders: his team members play all three roles.&lt;/p&gt;
&lt;h2&gt;Jason Fried, &lt;a href="http://37signals.com"&gt;37 Signals&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Jason Fried led off the second day and, thankfully, did not give yet another &amp;#8220;getting real&amp;#8221; talk but instead talked about the details that make a design great. Unsurprisingly, most of the examples came from 37 Signals products.&lt;/p&gt;
&lt;p&gt;It was interesting to see how much thought has gone into some of the hidden details. One of the hallmarks of such details is that when they&amp;#8217;re done right, you hardly notice them. But if they hadn&amp;#8217;t been done right, they&amp;#8217;d be annoyances.&lt;/p&gt;
&lt;p&gt;Ironically, as one of the often-cited &amp;#8220;Web 2.0&amp;#8221; applications, Basecamp and its brethren exhibit almost none of the classic &amp;#8220;Web 2.0&amp;#8221; visual design traits, such as rounded corners and gradients. 37 Signals has focused on usability, not on visual appeal.&lt;/p&gt;
&lt;p&gt;One essential practice, which would seem to be obvious but is somehow overlooked by far too many web applications, is really understanding the user&amp;#8217;s workflow and minimizing the number of clicks required to accomplish a task. As an example, Jason showed how few actions are required to create a new to-do list in &lt;a href="http://basecamphq.com"&gt;Basecamp&lt;/a&gt; and add items to it.&lt;/p&gt;
&lt;p&gt;Some other examples of details that make a difference:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Take care with copywriting: avoid technical terms, be explicit, write from the user&amp;#8217;s perspective. An example: in &lt;a href="http://thehighriseapp.com"&gt;Highrise&lt;/a&gt;, access rights for a contact aren&amp;#8217;t labeled &amp;#8220;permissions&amp;#8221;; the list is headed &amp;#8220;Who can access this contact&amp;#8221; and has choices like &amp;#8220;Only I can&amp;#8221;.&lt;/li&gt;
	&lt;li&gt;Event timing can be critical. Example: in Basecamp, an edit link appears to the left of a task when you hover over the task. But when you move your cursor to the edit link, it doesn&amp;#8217;t disappear immediately if you overshoot; it sticks around for a quarter of a second.&lt;/li&gt;
	&lt;li&gt;If you have multiple 37 Signals applications, you can now get a set of drop-down menus at the top of the page that let you move easily among them. Since you have to pass over these menus to get to the browser controls, the designers didn&amp;#8217;t want them flashing up. So&lt;br /&gt;
they don&amp;#8217;t pull down until you hover for them for 1/4 second.&lt;/li&gt;
	&lt;li&gt;Keep the user oriented when changes happen. For example, when completing a task, it appears crossed out briefly, then fades away, then disappears and space is reused.&lt;/li&gt;
	&lt;li&gt;Scrolling up the browser when inserting an ajax dialog, so the entire dialog and the submit button is visible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All this attention to detail is what sets a great design apart for the pack. &amp;#8220;The craftsman spends time on details because he doesn&amp;#8217;t know any other way&amp;#8221; &amp;#8212; great designs come from designers who are obsessed with the quality of what they&amp;#8217;re producing.&lt;/p&gt;
&lt;p&gt;In response to an audience question, Jason admitted that 37 Signals does not do any formal user testing; they just pay attention to feedback from real users. It no doubt helps that they&amp;#8217;re designing for users much like themselves.&lt;/p&gt;
&lt;h2&gt;Hagan Rivers, &lt;a href="http://tworivers.com"&gt;Two Rivers Consulting&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hagan Rivers gave an excellent talk showing examples of how she takes existing designs and makes them more usable and more attractive. She&amp;#8217;s been designing web applications since there was such a thing, and she and her husband run a design shop that specializes in &amp;#8220;application design makeovers.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Hagan put together a great set of visuals for this talk, and I can&amp;#8217;t begin to do justice to them in words. Here&amp;#8217;s her summary list of makeover tips:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Remove as much as you can&lt;/li&gt;
	&lt;li&gt;Be obsessive&lt;/li&gt;
	&lt;li&gt;Improve just one thing&lt;/li&gt;
	&lt;li&gt;Create strong groupings&lt;/li&gt;
	&lt;li&gt;Let data rise out&lt;/li&gt;
	&lt;li&gt;Beware the navigation that eats pixels&lt;/li&gt;
	&lt;li&gt;Leverage your templates&lt;/li&gt;
	&lt;li&gt;Watch out for technicolor headaches&lt;/li&gt;
	&lt;li&gt;A single purpose for each screen&lt;/li&gt;
	&lt;li&gt;Prioritize what&amp;#8217;s there&lt;/li&gt;
	&lt;li&gt;Never rest!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I had a web app that needed a design makeover, Two Rivers would definitely be on my short list of companies to ask for help.&lt;/p&gt;
&lt;h2&gt;Derek Featherstone, &lt;a href="http://www.furtherahead.com/"&gt;Further Ahead&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Derek addressed the issues of design for accessibility. This is a huge challenge for web application designers, and folks like Derek make a big contribution by evangelizing for better accessibility.&lt;/p&gt;
&lt;p&gt;Derek encouraged designers to look at the needs of impaired users holistically, and not to take a compliance-based checklist approach. To create an accessible application requires thinking through a lot of issues that just aren&amp;#8217;t on most designers&amp;#8217; minds.&lt;/p&gt;
&lt;p&gt;In my own work, I have to admit that I find it overwhelming to consider all the accessibility issues, when we&amp;#8217;re still working 110% on getting the core experience down. But as we become more intimate with what accessibility requires, it affects our coding style, and as we get further along in our development, we&amp;#8217;ll pay some particular attention to accessibility.&lt;/p&gt;
&lt;p&gt;Knowing when you&amp;#8217;ve done well isn&amp;#8217;t easy, either. Reading web pages with a screen reader is an art unto itself, and not one that a sighted designer or developer is likely to develop. So you really need to have contact with impaired users who can give you feedback on where your design creates problems for them.&lt;/p&gt;
&lt;p&gt;If you need help with design for accessibility, check out the consulting services that &lt;a href="http://www.furtherahead.com/"&gt;Further Ahead&lt;/a&gt; offers.&lt;/p&gt;
&lt;h2&gt;In Closing&lt;/h2&gt;
&lt;p&gt;Jared Spool brings a nice levity to his talks, and even performed magic tricks during some of the breaks. In this spirit, I&amp;#8217;ll close with one of his jokes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why are New Yorker&amp;#8217;s always depressed?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The light at the end of the tunnel is New Jersey&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=uKgvZ_lkal0:M0Nau6eC3mY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=uKgvZ_lkal0:M0Nau6eC3mY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=uKgvZ_lkal0:M0Nau6eC3mY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=uKgvZ_lkal0:M0Nau6eC3mY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/uKgvZ_lkal0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6502-jared-spool-s-web-app-summit</feedburner:origLink></entry>
  <entry>
    <title>File Upload Form Testing Fixtures</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/Mcxz9ZqRLkU/6411-file-upload-form-testing-fixtures" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6411-file-upload-form-testing-fixtures</id>
    <updated>2008-02-04T16:00:00Z</updated>
    <author>
      <name>Christopher Haupt</name>
    </author>
    <summary>Recently, I needed to write my first set of functional tests for a form that is used to upload image assets into our Content Management System. I wanted to find something as easy as fixtures for testing this part of our program.</summary>
    <content type="html">
&lt;p&gt;Recently, I needed to write my first set of functional tests for a form that is used to upload image assets into our Content Management System. I wanted to find something as easy as fixtures for testing this part of our program.&lt;/p&gt;
&lt;p&gt;Whether you are using &lt;a href="http://techno-weenie.net/"&gt;Rick Olson&amp;#8217;s&lt;/a&gt; excellent attachment_fu (see &lt;a href="http://clarkware.com/cgi/blosxom/2007/02/24"&gt;Mike Clark&amp;#8217;s nice tutorial&lt;/a&gt;), &lt;a href="http://uploadcolumn.rubyforge.org/"&gt;Sebastian Kanthak and Jonas Nicklas&amp;#8217; upload_column&lt;/a&gt;, or your own code that works with file uploads, you should test this workflow just like any other code path. At first, I thought this was going to be a painful task and require messing around with some custom File I/O or other marshaling trickery. Most of the documentation for 3rd party file upload implementations tended to have little or no information on testing.&lt;/p&gt;
&lt;p&gt;Then, while reading through the code a bit more, I stumbled upon &lt;a href="http://api.rubyonrails.org/classes/ActionController/TestProcess.html"&gt;fixture_file_upload&lt;/a&gt;. This convenience function is tucked away in ActionController&amp;#8217;s TestProcess module and is shorthand for instantiating the underlying ActionController::TestUploadedFile class. TestUploadedFile itself is a mock object that simulates the target file that my user would upload in a form or other interface via a &lt;span class="caps"&gt;&lt;span class="caps"&gt;MIME&lt;/span&gt;&lt;/span&gt; multipart/form-data &lt;span class="caps"&gt;&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To use this handy method, I simply put test files in a convenient directory within my fixtures directory, say &amp;#8220;files&amp;#8221;. Then in a test for upload_column, I write:&lt;/p&gt;
&lt;pre&gt;
def test_should_create_asset
    old_count = Asset.count
    post :create, :asset =&amp;amp;gt; { :title =&amp;amp;gt; "test", :file =&amp;amp;gt; fixture_file_upload('/files/testpicture1.jpg', 'image/jpeg') }
    assert_equal old_count+1, Asset.count
    assert_redirected_to asset_path(assigns(:asset))
 end
&lt;/pre&gt;
&lt;p&gt;Here, the :file attribute for my asset model is expecting an uploaded file from my form, so I feed it one from my fixtures/files directory.&lt;/p&gt;
&lt;p&gt;If I use attachment_fu, I may write a create test:&lt;/p&gt;
&lt;pre&gt;
  def test_should_create_asset
    old_count = Asset.count
    post :create, :asset =&amp;amp;gt; { :name =&amp;amp;gt; 'railslogo', :uploaded_data =&amp;amp;gt; fixture_file_upload('/files/rails.png', 'image/png') },
                   :html =&amp;amp;gt; {:multipart =&amp;amp;gt; true }
    assert_equal old_count+1, Asset.count

  end
&lt;/pre&gt;
&lt;p&gt;or an update test:&lt;/p&gt;
&lt;pre&gt;
  def test_should_update_asset
    put :update, {:id =&amp;amp;gt; assets(:one).id, :asset =&amp;amp;gt; { :uploaded_data =&amp;amp;gt; fixture_file_upload('/files/rails.png', 'image/png') }}
    assert_redirected_to asset_path(assigns(:asset))
  end
&lt;/pre&gt;
&lt;p&gt;The TestUploadedFile class is not limited to image data. It can channel any type I may wish into the request. Its default content type assumes text/plain.&lt;/p&gt;
&lt;p&gt;Now I can proceed to write a suite of tests for my file upload use cases and let Action Controller and the fixture_file_upload helper do the heavy lifting.&lt;/p&gt;
&lt;h3&gt;Other Resources&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.subelsky.com/2007/05/functional-testing-for-attachment-fu.html"&gt;Mike Subelsky&amp;#8217;s Blog Entry about testing Attachment_fu&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.beckshome.com/PermaLink,guid,560613dd-217c-4cb1-a6b9-df83a55191e7.aspx"&gt;Thomas Beck&amp;#8217;s Blog Entry about multi-model tests with Attachment_fu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Mcxz9ZqRLkU:KxPKHWpBM4c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Mcxz9ZqRLkU:KxPKHWpBM4c:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=Mcxz9ZqRLkU:KxPKHWpBM4c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=Mcxz9ZqRLkU:KxPKHWpBM4c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/Mcxz9ZqRLkU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6411-file-upload-form-testing-fixtures</feedburner:origLink></entry>
  <entry>
    <title>2007: The Ruby on Rails Year in Review</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/WBggRSe59mE/6409-2007-the-ruby-on-rails-year" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6409-2007-the-ruby-on-rails-year</id>
    <updated>2008-01-08T16:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>Ruby on Rails had a very good year in 2007, continuing to gain traction as one of the leading web development frameworks and making progress on many fronts.</summary>
    <content type="html">
&lt;p&gt;Ruby on Rails had a very good year in 2007, continuing to gain traction as one of the leading web development frameworks and making progress on many fronts. Although it is not yet nearly as widely used as &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt;, Java, or .Net, it has become perhaps the most common platform for web startups, at least within the &amp;#8220;Web 2.0&amp;#8221; space.&lt;/p&gt;
&lt;p&gt;In addition to all the startups that launched in 2007 using Rails-based applications, many established companies converted existing applications or began new ones using Rails. Some examples:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.yellowpages.com"&gt;Yellowpages.com&lt;/a&gt; replaced a J2EE system with a new Ruby on Rails application. This may be the highest-volume Rails site currently operating.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt; added a new kind of instant messaging, with an application that seriously stressed the scalability of Rails.&lt;/li&gt;
	&lt;li&gt;The originators of Rails, 37Signals, added the &lt;a href="http://highrisehq.com"&gt;Highrise&lt;/a&gt; contact-management application to their portfolio.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://revolutionhealth.com"&gt;Revolution Health&lt;/a&gt; is a large health information site led by Steve Case.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://microplace.com"&gt;MicroPlace&lt;/a&gt;, a microfinance investing site, is owned by eBay &amp;#8212; until now, a hard-core Java shop.&lt;/li&gt;
	&lt;li&gt;Yahoo, until now mostly a &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; shop, began alpha testing a new geolocation platform, called &lt;a href="http://fireeagle.research.yahoo.com/"&gt;FireEagle&lt;/a&gt;, which is written in Rails.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;New Versions of Everything&lt;/h2&gt;
&lt;p&gt;The big news on the technical side was the release of version 1.2 early in the year and version 2.0 at the end of year. There were also major new releases of key related programs, including Capistrano 2.0, Prototype 1.6, and Scriptaculous 1.8.&lt;/p&gt;
&lt;p&gt;Rails is still very young, but it is no longer a newborn. Basecamp, the application from which Rails was originally extracted, is now almost four years old. To be sure, there have been some teething pains, and a few people who have vocally abandoned Rails. But Rails is clearly a healthy adolescent, with a great future as an adult ahead of it.&lt;/p&gt;
&lt;p&gt;Rails 2.0 shows signs of a maturing framework; despite the &amp;#8220;major&amp;#8221; version number, the changes are more incremental than those from 1.1 to 1.2, and there&amp;#8217;s more attention to backward compatibility.&lt;/p&gt;
&lt;h2&gt;Rails Community Growth&lt;/h2&gt;
&lt;p&gt;The Rails community, whatever you may mean by that, grew dramatically in 2007.&lt;/p&gt;
&lt;p&gt;No doubt there are many more people building with Rails today than there were a year ago, though we haven&amp;#8217;t been able to come up with a specific way to measure that.&lt;/p&gt;
&lt;p&gt;The past year has seen an amazing proliferation of Ruby on Rails books. At the start of the year, I had 5 Ruby and Ruby on Rails books on my shelf. I may have missed one or two, but not more than that. One year later, I now have 27 books on Ruby and Rails.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a dozen or so introductory books now, with dozens of application examples, as well as one outstanding new reference book: &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321445619/buildicom-20"&gt;The Rails Way&lt;/a&gt;. And there&amp;#8217;s specialty books on topics including mapping, social networking, Active Record, and Prototype and Scriptaculous.&lt;/p&gt;
&lt;p&gt;RailsConf in May 2007 attracted a sell-out crowd of more than 1,600 attendees, triple the previous year&amp;#8217;s attendance, and organizer O&amp;#8217;Reilly said it was their fastest-selling conference ever. The was also a successful RailsConf in Europe in the fall, several regional RailsEdge conferences, a larger-than-ever, sold-out RubyConf, and many smaller events.&lt;/p&gt;
&lt;h2&gt;Strife at the Fringes&lt;/h2&gt;
&lt;p&gt;Like any large and growing community, the Rails community has its detractors. In a recent article, which got a lot of attention because it was, in a peculiar way, a fun read, Zed Shaw &lt;a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html"&gt;attacked the Rails community&lt;/a&gt; and proclaimed his plan to move away from Ruby and Rails. As the author of Mongrel, the application server used by the vast majority of Rails apps in production today, Zed&amp;#8217;s programming chops are unquestioned. But we find it unfortunate that he&amp;#8217;s created an &amp;#8220;us&amp;#8221; vs. &amp;#8220;them&amp;#8221; situation, and that he turns technical disagreements into personal attacks on other people.&lt;/p&gt;
&lt;p&gt;Another notable &lt;a href="http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html"&gt;article was written by CD Baby creator Derek Sivers&lt;/a&gt;, after he gave up on a two-year effort to rewrite his &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt; site in Rails, and went back to &lt;span class="caps"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/span&gt;. The key point of this piece, as we see it, is that if you are expert in a technology and you have a detailed idea of what you want to build, it can be frustrating to switch to another technology, especially one that makes you learn new ways to make things easy, and that constrains how you can implement things.&lt;/p&gt;
&lt;p&gt;Part of what makes Rails great is its &amp;#8220;opinionated&amp;#8221; design, and of course that means there are opinionated people at the heart of the Rails community. A small group of people holds a great deal of power over Rails, and if you happen to disagree with that group, it can be painful. Our experience has been that the vast majority of people in the Rails community are smart, friendly, and contribute a lot.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a few people, including David H. Hansson, Dave Thomas, Mike Clark, Chad Fowler, Michael Koziarsky, and Jim Weirich, without whom we just wouldn&amp;#8217;t have the Rails software and community as we have it today. Many others no doubt belong on this list as well. They&amp;#8217;ve made incredible contributions during the past few years. Remember that, in most cases, no one is paying anyone to build and maintain the Rails framework. (This not to say that these people haven&amp;#8217;t built businesses around Rails, of course, as we have.)&lt;/p&gt;
&lt;h2&gt;The Rise of &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Perhaps the most far-reaching change in Rails during the past year has been the whole-hearted adoption of RESTful design practices. Rails 2.0 eliminates the old scaffold entirely and replaces it with what had been called resource_scaffold, which is indicative of the core team&amp;#8217;s belief that all applications should be designed as a set of resources with RESTful interfaces. &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt; even got a book of its own in 2007: the surprisingly readable &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596529260/buildicom-20"&gt;RESTful Web Services&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The rise to prominence of the RESTful approach has many advantages, but it does present additional hurdles for newcomers learning Rails. Conventional routes are easier to understand, but with the scaffold no longer using them, new users will be thrust immediately into &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt;. At least it is now clear that there&amp;#8217;s really no alternative to coming to grips with &lt;span class="caps"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/span&gt; if you want to follow the Rails golden path.&lt;br /&gt;
	&lt;br /&gt;
h2. Development Tools Proliferate&lt;/p&gt;
&lt;p&gt;A year ago, you wouldn&amp;#8217;t find many Rails developers using an &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;. TextMate and the console were, and remain, the most widely used development setup. But IDEs are gaining ground.&lt;/p&gt;
&lt;p&gt;At the end of 2006, the open-source RadRails project, based on Eclipse, began gaining some traction. In early 2007, RadRails was acquired by Aptana, which has now built a much enhanced version of the Rails support from RadRails into its &lt;a href="http://aptana.com"&gt;Aptana Studio&lt;/a&gt; development environment.&lt;/p&gt;
&lt;p&gt;Sun lent its support to Rails with the introduction of Ruby and Rails support for &lt;a href="http://www.netbeans.org"&gt;NetBeans&lt;/a&gt;. NetBeans 6.0 went through a series of beta releases, culminating in the official release late in 2007. NetBeans works either with Sun&amp;#8217;s JRuby or with the native Ruby interpreter.&lt;/p&gt;
&lt;p&gt;And there&amp;#8217;s more &amp;#8212; Borland&amp;#8217;s &lt;a href="http://www.codegear.com/products/3rdrail/"&gt;CodeGear&lt;/a&gt; now supports Rails, ActiveState offers Rails support in its &lt;a href="http://www.activestate.com/Products/komodo_ide/"&gt;Komodo&lt;/a&gt; &lt;span class="caps"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/span&gt;, and SapphireSteel offers &lt;a href="http://www.sapphiresteel.com/"&gt;Ruby in Steel&lt;/a&gt;, a set of Ruby extensions for Microsoft&amp;#8217;s Visual Studio.&lt;/p&gt;
&lt;h2&gt;Looking Forward&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll save most of our prognostications about the future for other articles. But one key trend to watch in 2008 is the emergence of Rails running on various virtual machines, including Ruby 1.9, JRuby, Rubinious, and IronRuby. By the end of the year, it will probably be a lot harder to attack Ruby on the basis of its being slow.&lt;/p&gt;
&lt;h2&gt;What Did We Miss?&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ve touched on just a few highlights in this article. What do you think were the most significant Rails events of 2007? Add your comments and we&amp;#8217;ll update the article after a bit with the most notable additions.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=WBggRSe59mE:SKv_ph0BSAU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=WBggRSe59mE:SKv_ph0BSAU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=WBggRSe59mE:SKv_ph0BSAU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=WBggRSe59mE:SKv_ph0BSAU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/WBggRSe59mE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6409-2007-the-ruby-on-rails-year</feedburner:origLink></entry>
  <entry>
    <title>Better Rails Scaffolding</title>
    <link href="http://feedproxy.google.com/~r/buildingwebappsarticles/~3/X5SdtuUTNVw/6395-better-rails-scaffolding" rel="alternate" />
    <id>http://buildingwebapps.com/articles/6395-better-rails-scaffolding</id>
    <updated>2007-12-31T16:00:00Z</updated>
    <author>
      <name>Michael Slater</name>
    </author>
    <summary>One of the things that created a lot of early attention for Rails was the scaffolding, which makes it possible to create an instant admin interface for your database tables. While the built-in scaffolding was interesting two years ago, it clearly has received no attention from the core team, which ...</summary>
    <content type="html">
&lt;p&gt;One of the things that created a lot of early attention for Rails was the scaffolding, which makes it possible to create an instant admin interface for your database tables. While the built-in scaffolding was interesting two years ago, it clearly has received no attention from the core team, which doesn&amp;#8217;t use it. It is really pretty horrible; for example:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The standard &lt;span class="caps"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt; is really, really ugly&lt;/li&gt;
	&lt;li&gt;It deals with only one table at a time and ignores associations&lt;/li&gt;
	&lt;li&gt;It is hard to customize; generally, you end up just stripping it out and replacing it&lt;/li&gt;
	&lt;li&gt;It doesn&amp;#8217;t use any &lt;span class="caps"&gt;&lt;span class="caps"&gt;AJAX&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There have been various attempts to build a better solution; the two best-known are &lt;a href="http://www.streamlinedframework.org"&gt;Streamlined&lt;/a&gt; and Ajax Scaffold. The latter evolved into &lt;a href="http://www.activescaffold.com"&gt;ActiveScaffold&lt;/a&gt;, which yesterday reached a big milestone: version 1.0 was released. I haven&amp;#8217;t yet had a chance to deeply evaluate the two against each other, but one thing is clear: there&amp;#8217;s no longer any reason to use the standard scaffolding.&lt;/p&gt;
&lt;p&gt;Unlike many Rails plugins, ActiveScaffold actually has &lt;a href="http://www.activescaffold.com/docs/"&gt;extensive documentation&lt;/a&gt;. I&amp;#8217;m looking forward to being able to actually use scaffolding for admin functions now instead of having to build them from scratch. It&amp;#8217;s great to be using a framework with such an active developer community that dives in and solves problems such as this one. And, of course, it&amp;#8217;s all open source.&lt;/p&gt;    &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=X5SdtuUTNVw:RnQUCvn0PDc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=X5SdtuUTNVw:RnQUCvn0PDc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/buildingwebappsarticles?a=X5SdtuUTNVw:RnQUCvn0PDc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/buildingwebappsarticles?i=X5SdtuUTNVw:RnQUCvn0PDc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/buildingwebappsarticles/~4/X5SdtuUTNVw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://buildingwebapps.com/articles/6395-better-rails-scaffolding</feedburner:origLink></entry>
</feed>
