<?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>Spitfire Sky Blog</title>
  <subtitle>web development blog</subtitle>
  
  <link href="http://spitfiresky.com/" />
  <updated>2011-06-12T16:17:24-07:00</updated>
  <author>
    <name>scottmotte</name>
    <email>scott@spitfiresky.com</email>
  </author>
  <id>http://spitfiresky.com/</id>
  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/spitfiresky" /><feedburner:info uri="spitfiresky" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>spitfiresky</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry>
    <title>Add Gaming Elements to your Apps</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/IW_xOYoxfng/add-gaming-elements-to-your-apps.html" />
    <id>tag:spitfiresky.com,Sun Jun 12 13:37:08 -0700 2011:1307911028</id>
    <updated>Sun Jun 12 13:37:08 -0700 2011</updated>
    <content type="html">&lt;h2&gt;Add Gaming Elements to your Apps&lt;/h2&gt;
&lt;p&gt;Gaming is big now - especially mobile gaming. Let's strive to add gaming elements to our 'boring' applications.&lt;/p&gt;
&lt;h3&gt;Gaming and Real Life&lt;/h3&gt;
&lt;p&gt;Jane McGonigal did a TED Talk on how gaming can make a better world. It was an exuberant and inspiring presentation. Here's the &lt;a href='http://www.ted.com/talks/jane_mcgonigal_gaming_can_make_a_better_world.html'&gt;link to the video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I liked her ideas about leveling up and +1 strength. Those concepts which are a part of the virtual world but not a part of the real world can make virtual life more rewarding than real life - at least more immediately rewarding.&lt;/p&gt;
&lt;p&gt;This is why there is an exodus of people to these virtual worlds like World of Warcraft. 3 billion hours a week is spent playing online games.&lt;/p&gt;
&lt;p&gt;Jane sees opportunity in this and I do too. In fact, she says we should be playing even more games. We just need to make games applicable to real life.&lt;/p&gt;
&lt;p&gt;I think we as web developers can do this by bringing more gaming elements to the applications we can create.&lt;/p&gt;
&lt;h3&gt;EpicWin&lt;/h3&gt;
&lt;p&gt;
  &lt;img src='/images/gaming_elements/epicwin.png' width='500' /&gt;
&lt;/p&gt;
&lt;p&gt;The iPhone application &lt;a href="http://www.rexbox.co.uk/epicwin/"&gt;EpicWin&lt;/a&gt; does a nice job of this as a todo task I think. I've used EpicWin for a few months now and like it much better than even &lt;a href="http://culturedcode.com/things/"&gt;Things&lt;/a&gt;. This &lt;a href="http://www.youtube.com/watch?v=AmKwF_Si734&amp;feature=player_embedded"&gt;1 minute trailer for EpicWin&lt;/a&gt; sums it up better than I can in words.&lt;/p&gt;
&lt;p&gt;I get more done with EpicWin. Its gaming mechanism of earning experience points and leveling up has motivated me to get much more done - exercise consistently to build strength, self-educate myself on a daily basis to increase intellect, and even take more time out with friends to increase my social score.&lt;/p&gt;
&lt;h3&gt;My Attempt at Adding Gaming Elements&lt;/h3&gt;
&lt;p&gt;I've only just begun adding gaming elements to my application designs. My first attempt is &lt;a href="http://motopermit.heroku.com/"&gt;MotoPermit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is a study application for the motorcycle permit test. I launched it by making it "look" like a game. This was a cop-out for the real thing. Apps that integrate gaming elements do not need to 'look' like a game, they need to function more like one.&lt;/p&gt;
&lt;p&gt;So after launching the app I set to work on version 1.1 - which would add gaming elements. I've since added a basic experience point and profile mechanism. Each correctly answered question is worth 50 experience points. After you accumulate 1500 experience points, you level up. Reach level 5 and you are ready to take your motorcycle permit test.&lt;/p&gt;
&lt;p&gt;
  &lt;table class='no_border align_center'&gt;
    &lt;tr&gt;
      &lt;td&gt;
        &lt;img src='/images/gaming_elements/motopermit1.png' width='200' /&gt;
      &lt;/td&gt;
      &lt;td&gt;
        &lt;img src='/images/gaming_elements/motopermit2.png' width='200' /&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;I've found myself using the app much more in order to more quickly reach level 5. And I am confident that once I do reach level 5 I will be ready to take the permit test and pass it my first time. It's done it's purpose to help me study better and I think it will do the same for others.&lt;/p&gt;
&lt;p&gt;So try to start adding gaming elements to your applications. You will find them more effective. &lt;strong&gt;And over time maybe we truly can step towards making the world better through gaming.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    Follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/add-gaming-elements-to-your-apps.html</feedburner:origLink></entry>
  
  <entry>
    <title>Provisioning a Titanium Mobile App</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/Sdj36GG9R3s/provisioning-titanium-mobile-app.html" />
    <id>tag:spitfiresky.com,Mon Apr 25 20:54:43 -0700 2011:1303790083</id>
    <updated>Mon Apr 25 20:54:43 -0700 2011</updated>
    <content type="html">&lt;h2&gt;Provisioning a Titanium Mobile App&lt;/h2&gt;
&lt;p&gt;Keys, Certificates, Provisioning Profiles, and AppIDS can be a configuration nightmare. In this article, I step through setting these up with a Titanium Mobile app.&lt;/p&gt;
&lt;h3&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;You need the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;An Apple Developer's Account&lt;/li&gt;
  &lt;li&gt;A Mac&lt;/li&gt;
  &lt;li&gt;An iPhone, iPad, or iPod&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Certificates, Keys, Provision Profiles, AppIDs&lt;/h3&gt;
&lt;h4&gt;Generate key&lt;/h4&gt;
&lt;p&gt;Just follow along.&lt;/p&gt;
&lt;p&gt;On your mac open up Keychain Access. In the toolbar click 'Keychain Access' -&gt; 'Certificate Assistant' -&gt; 'Request a Certificate from a Certificate Authority'.&lt;/p&gt;
&lt;img src='/images/push_notifications/1.png' /&gt;
&lt;p&gt;In the pop up window, use the email address you signed up on the Apple Developer's site with. Enter your name, and choose Save to Disk.&lt;/p&gt;
&lt;img src='/images/push_notifications/2.png' /&gt;
&lt;p&gt;Save it somewhere you can easily find it. Keep it safe.&lt;/p&gt;
&lt;img src='/images/push_notifications/3.png' /&gt;
&lt;h4&gt;App IDs&lt;/h4&gt;
&lt;p&gt;Login into your development account, visit the iPhone Developer Program Portal, and go to the App IDs section: &lt;a href="http://developer.apple.com/iphone/manage/bundles/index.action"&gt;http://developer.apple.com/iphone/manage/bundles/index.action&lt;/a&gt;&lt;/p&gt;
&lt;img src='/images/push_notifications/4.png' /&gt;
&lt;p&gt;Click the New App ID button, and on the next page enter a name (MissMint) and a bundle identifier (com.spitfiresky.missmint).&lt;/p&gt;
&lt;img src='/images/push_notifications/5.png' /&gt;
&lt;p&gt;After creating the AppID go to configure the id you just created. On the next page, check the box to 'Enable for Apple Push Notification service', and then click the 'Configure' button next to the Development Push SSL Certificate.&lt;/p&gt;
&lt;img src='/images/push_notifications/6.png' /&gt;
&lt;p&gt;In the configuration window, follow the steps, and upload the CerticiateSigningRequest file we created previously using KeyChain Access.&lt;/p&gt;
&lt;img src='/images/push_notifications/7.png' /&gt;
&lt;p&gt;Next download your newly generated push notification ssl certificate.&lt;/p&gt;
&lt;img src='/images/push_notifications/8.png' /&gt;
&lt;p&gt;Double click on this certificate to save it your key chain. Export this key by clicking on this newly installed certificate.&lt;/p&gt;
&lt;p&gt;Next, go back to the Apple Developer website, go to provisioning profiles, and choose to a create a new provisioning profile. &lt;a href="http://developer.apple.com/iphone/manage/provisioningprofiles/create.action?type=1"&gt;http://developer.apple.com/iphone/manage/provisioningprofiles/create.action?type=1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fill in the form with the appropriate info.&lt;/p&gt;
&lt;img src='/images/push_notifications/9.png' /&gt;
&lt;p&gt;Download the newly created provisioning profile.&lt;/p&gt;
&lt;img src='/images/push_notifications/10.png' /&gt;
&lt;p&gt;Open up Titanium Mobile and open up your project. Go to Test &amp; Package, and then the Running your app on a device section. On the 'Select Provisioning Profile' section choose to browse for the provisioning profile we just downloaded.&lt;/p&gt;
&lt;img src='/images/push_notifications/11.png' /&gt;
&lt;p&gt;Choose the provisioning profile we just downloaded.&lt;/p&gt;
&lt;img src='/images/push_notifications/12.png' /&gt;
&lt;p&gt;Open up xcode with your iphone plugged into your computer and drag the provisioning profile onto the window.&lt;/p&gt;
&lt;img src='/images/push_notifications/13.png' /&gt;
&lt;p&gt;You might have to quit Titanium Mobile and iTunes at this point to finally get everything working. Re-open them and then in Titanium Mobile install the app onto your phone by pressing "Install Now".&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/provisioning-titanium-mobile-app.html</feedburner:origLink></entry>
  
  <entry>
    <title>Ad Hoc Distributing a Titanium Mobile App</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/W9S6p_iOk4k/ad-hoc-distributing-a-titanium-mobile-app.html" />
    <id>tag:spitfiresky.com,Mon Apr 25 20:54:43 -0700 2011:1303790083</id>
    <updated>Mon Apr 25 20:54:43 -0700 2011</updated>
    <content type="html">&lt;h2&gt;Ad Hoc Distributing a Titanium Mobile App&lt;/h2&gt;
&lt;p&gt;Ad Hoc Distribution allows you to test your app on your iPhone and other friend's iPhones.&lt;/p&gt;
&lt;h3&gt;1: Create an Ad Hoc Distribution Provisioning Profile&lt;/h3&gt;
&lt;p&gt;Navigate to the &lt;a href='http://developer.apple.com/ios/manage/provisioningprofiles/viewDistributionProfiles.action'&gt;Distribution Provisioning Profiles&lt;/a&gt; section of the iOS Provisioning Portal. Then click on 'New Profile'.&lt;/p&gt;
&lt;p&gt;In the &lt;a href='http://developer.apple.com/ios/manage/provisioningprofiles/create.action?type=2'&gt;'Create iOS Distribution Provisioning Profile' screen&lt;/a&gt;, choose the Ad Hoc distribution method, give it a name like 'Your App Ad Hoc Distribution Profile', select the App ID which you created earlier, and then select the Device(s) you want it to work on. Note: you will have to add your friends' devices here in order for the app to work on their iPhone. You can gather this device information using &lt;a href='http://testflightapp.com'&gt;testflightapp.com&lt;/a&gt;.&lt;/p&gt;
&lt;p align='center'&gt;
  &lt;img src='/images/ad_hoc_distribution/0.png' width='500' /&gt;
&lt;/p&gt;
&lt;p&gt;After saving that download it to your computer. Double click on it and it will ask you to add it to 'Add to Library'. Please do.&lt;/p&gt;
&lt;h3&gt;2: Set Titanium Mobile's Distribute section to use the Provisioning Profile&lt;/h3&gt;
&lt;p&gt;Open up Titanium Mobile and navigate to Your Project &gt; Test &amp;amp; Package &gt; Distribute. Choose 'Desktop' for your distribution location and select the distribution provisioning profile you just downloaded to your computer in the steps above. (if it asks you to 'Add to Library' again go ahead and do so and replace the existing ad hoc distribution profile)&lt;/p&gt;
&lt;p align='center'&gt;
  &lt;img src='/images/ad_hoc_distribution/1.png' width='500' /&gt;
&lt;/p&gt;
&lt;h3&gt;3: Distribute Your App&lt;/h3&gt;
&lt;h4&gt;Titanium&lt;/h4&gt;
&lt;p&gt;Quit Titanium and the re-open it.&lt;/p&gt;
&lt;p&gt;Navigate to the Distribution section under Test &amp;amp; Package and click 'Package' (make sure XCode is open in the background before clicking 'Package')&lt;/p&gt;
&lt;h4&gt;Generate the .ipa file&lt;/h4&gt;
&lt;p&gt;After Titanium is done packaging your app it should open up 'Organizer' on your mac. Click on the Archives tab in Organizer. You should see your app listed in the Archives.&lt;/p&gt;
&lt;p&gt;Click on the name of your app and then click the 'Share' button. This will pop up a window. In that window choose iOS App Store Package (.ipa) and for Identity choose the option right underneath the Ad Hoc Distribution Profile we created earlier. It should probably say iPhone Distribution: Your Name.&lt;/p&gt;
&lt;p&gt;Click 'Next' and then save the app to your Desktop. It is a good idea to name the app without any spaces - ie YourAppname&lt;/p&gt;
&lt;h4&gt;Use TestFlight to upload your app&lt;/h4&gt;
&lt;p&gt;Go to &lt;a href="http://testflightapp.com"&gt;testflightapp.com&lt;/a&gt; and create a developer account.&lt;/p&gt;
&lt;p&gt;Choose Builds &gt; Upload a Build and upload your YourAppname.ipa file you saved to your desktop. Once the upload is complete, choose your testers and they will receive an email with a link to download your app to their iPhone.&lt;/p&gt;
&lt;p&gt;That is it. Best of luck.&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/ad-hoc-distributing-a-titanium-mobile-app.html</feedburner:origLink></entry>
  
  <entry>
    <title>An App - Scottbalance</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/Zy0jSjBzEp0/an-app-scottbalance.html" />
    <id>tag:spitfiresky.com,Thu Dec 30 23:00:00 -0800 2010:1293778800</id>
    <updated>Thu Dec 30 23:00:00 -0800 2010</updated>
    <content type="html">&lt;h2&gt;An App - Scottbalance&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://scottbalance.heroku.com/"&gt;Scottbalance&lt;/a&gt; (&lt;a href="http://spitfiresky.com/portfolio/scottbalance.html"&gt;portfolio link&lt;/a&gt;) is a tiny app with a simple role. It saves a daily history of your Scottrade account balance and emails it to you - automatically.&lt;/p&gt;
&lt;h3&gt;Why this app?&lt;/h3&gt;
&lt;p&gt;I have an account with &lt;a href="http://scottrade.com"&gt;Scottrade&lt;/a&gt; where I invest in stocks. Scottrade does not include a feature to view your historical balances. It only shows your current day's balance. Scottrade does not provide an API to gather said historical balances either. I needed to be able to get a hold of my historical balances, so I built &lt;a href="http://scottbalance.heroku.com"&gt;Scottbalance.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;img src="/images/portfolios/scottbalance-1.jpg" width="545"&gt;
&lt;/p&gt;
&lt;h3&gt;How does it work?&lt;/h3&gt;
&lt;p&gt;Using your Scottrade login information, the app screen scrapes your latest current balance and saves that information to your balance history. (Your login information is securely encrypted). After saving it, it emails you to let you know your latest balance for that day. Then by logging in you can see a list of your historical balances.&lt;/p&gt;
&lt;p&gt;Additionally, the app is smart enough to navigate through Scottrade's new security questions. And the app is designed to look good on your iphone so you can check your balances on the go.&lt;/p&gt;
&lt;h3&gt;Libraries and Tools Used&lt;/h3&gt;
&lt;p&gt;The app is hosted on &lt;a href="http://heroku.com"&gt;heroku&lt;/a&gt;. It is built on &lt;a href="http://www.padrinorb.com/"&gt;Padrino&lt;/a&gt;. It uses &lt;a href="http://rubygems.org/gems/bcrypt-ruby"&gt;bcrypt&lt;/a&gt; to encrypt all Scottrade access information.  It uses &lt;a href="http://rubygems.org/gems/warden"&gt;warden&lt;/a&gt; to handle user authentication. For the automatic logging into Scottrade and for the screenscraping of the balances it uses &lt;a href="http://rubygems.org/gems/mechanize"&gt;mechanize&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This was a personal project so it's certainly not polished but it does its job well. So I decided to make it available to everyone. If you also have a Scottrade account, then &lt;a href="http://scottbalance.heroku.com/users/new"&gt;try it out&lt;/a&gt; and see what you think. It's free to use.&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    To follow me on twitter click
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/an-app-scottbalance.html</feedburner:origLink></entry>
  
  <entry>
    <title>Riverside Ruby - Introduction to Ruby</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/ibL5xWu2v7Y/riverside-ruby-introduction-to-ruby.html" />
    <id>tag:spitfiresky.com,Tue Sep 28 09:37:28 -0700 2010:1285691848</id>
    <updated>Tue Sep 28 09:37:28 -0700 2010</updated>
    <content type="html">&lt;h2&gt;Riverside Ruby - Introduction to Ruby&lt;/h2&gt;
&lt;p&gt;Here are the slides from my presentation to our first Riverside Ruby Meetup.&lt;/p&gt;
&lt;h3&gt;Slides&lt;/h3&gt;
&lt;object id="__sse5303192" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=konnichiwaruby-100927233029-phpapp02&amp;stripped_title=kon-nichi-waruby&amp;userName=scottmotte" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5303192" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=konnichiwaruby-100927233029-phpapp02&amp;stripped_title=kon-nichi-waruby&amp;userName=scottmotte" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
For this presentation I introduced ruby and some basics about the language. Additionally, I demonstrated the power and simplicity of ruby by using Sinatra to build a hello world app.
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/riverside-ruby-introduction-to-ruby.html</feedburner:origLink></entry>
  
  <entry>
    <title>Getting Started with Sinatra</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/Rgy4ryiuRzU/getting-started-with-sinatra.html" />
    <id>tag:spitfiresky.com,Mon May 31 18:16:33 -0700 2010:1275354993</id>
    <updated>Mon May 31 18:16:33 -0700 2010</updated>
    <content type="html">&lt;h2&gt;Getting Started with Sinatra&lt;/h2&gt;
&lt;p&gt;
  Sing me a song mister Sinatra. In this tutorial I get you started with sinatra, plus improve the folder structure of your app, and serve it up with unicorn.
&lt;/p&gt;
&lt;h3&gt;
  Installation
&lt;/h3&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420466.js?file=gistfile1.txt"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h3&gt;
  The Basics
&lt;/h3&gt;
&lt;p&gt;
  &lt;strong&gt;
    Type
    sudo mate hello.rb
  &lt;/strong&gt;
  and in the hello.rb put the following:
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420468.js?file=hello.rb"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Now you just need to run the app. Shotgun is great for this. It's a lot like script/server for unicorn apps.
  &lt;small&gt;
    (We'll use unicorn to do this later, but for now we'll keep it easy with shotgun)
  &lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420470.js?file=gistfile1.txt"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;strong&gt;
  haml
&lt;/strong&gt;
&lt;p&gt;
  I like haml so let's bring it into the app now. We've already installed the haml gem so just change your hello.rb file to the following:
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420473.js?file=hello.rb"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h3&gt;
  Move to folder structure
&lt;/h3&gt;
&lt;p&gt;
  I like an organized application that can handle future complexity. Let's setup a folder structure to make room for that possibility.
&lt;/p&gt;
&lt;p&gt;
  To begin, create a folder with the name of your app. I'm going to call my app careengine. Then, create the directory structure we'll be using.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420483.js?file=gistfile1.txt"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  In app.rb put the following:
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420485.js?file=app.rb"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  This tells our / route to use index.haml from our views. Let's create that file now by type sudo mate views/index.haml.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420486.js?file=index.haml"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h3&gt;
  Unicorn
&lt;/h3&gt;
&lt;p&gt;
  Now that the app is contained inside a folder structure (slightly similar to rails), let's set the app up to serve itself with unicorn instead of shotgun. (Unicorn is what we will be using on our production server, and It's nice to keep development and production as similar as possible.)
&lt;/p&gt;
&lt;p&gt;
  &lt;small&gt;
    Don't forget to install unicorn:
    &lt;strong&gt;
      sudo gem install unicorn
    &lt;/strong&gt;
  &lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
  Unicorn works with a config.ru file so let's create that.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;
    Type sudo mate config.ru
  &lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/420493.js?file=config.ru"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Now just run the command 'unicorn' in terminal and then browse to http://localhost:8080 to view your app. Alternatively you can type unicorn -p 3000 to specify the port as 3000.
&lt;/p&gt;
&lt;p&gt;
  Great work, you setup a basic sinatra app, improved on the structure, and served it up with unicorn. You are well on your way to building more complex sinatra applications.
&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should
    &lt;a href='http://twitter.com/spitfiresky'&gt;follow me on twitter here.&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/getting-started-with-sinatra.html</feedburner:origLink></entry>
  
  <entry>
    <title>How you should be doing testing in Rails and how to get started</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/TH5xKC65YY0/how-you-should-be-doing-testing-in-rails.html" />
    <id>tag:spitfiresky.com,Sat Oct 03 16:00:05 -0700 2009:1254610805</id>
    <updated>Sat Oct 03 16:00:05 -0700 2009</updated>
    <content type="html">&lt;h2&gt;How you should be doing testing in Rails and how to get started&lt;/h2&gt;
&lt;p&gt;Here I show you a good way to do testing in Rails (especially if you are a beginner tester) plus instructions on getting started.&lt;/p&gt;
&lt;h3&gt;Why test?&lt;/h3&gt;
&lt;p&gt;
  Testing is a good practice. You should be doing it. &lt;strong&gt;It will make you a better programmer&lt;/strong&gt; and save you a great deal of headache as your web app grows up. It is especially important when working alongside other programmers. Testing is not perfect though so don't try to be perfect. Just get started, and you will improve as time goes on.
&lt;/p&gt;
&lt;h3&gt;How should I be testing?&lt;/h3&gt;
&lt;p&gt;
  You should be:
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;#1 using rspec&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;#2 testing your models&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;#3 doing some integration tests&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  Ignore all the other test strategies and tools out there - especially Cucumber (cuke makes me want to puke). It's awkward and arguably a significant waste of time. But it's even more a waste of time to test your controllers, helpers, and views separately. Don't.
&lt;/p&gt;
&lt;p&gt;
  Let's get started.
&lt;/p&gt;
&lt;h3&gt;rspec&lt;/h3&gt;
&lt;h4&gt;Installation&lt;/h4&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200971.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  That's it, you can now run 'rake spec' in your terminal, and it will run through all your specs (which are currently at zero count).
&lt;/p&gt;
&lt;h3&gt;Model testing&lt;/h3&gt;
&lt;h4&gt;
  Setup
&lt;/h4&gt;
&lt;p&gt;Before we get to the rspec testing we need to delete the test/* folder that rails creates by default. (We are using rspec, not test/unit, so we won't need the test/* folders. All our tests will live under spec/*.)&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200982.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Next let's create the models folder and the person_spec.rb model spec.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200986.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h4&gt;
  Writing the model test
&lt;/h4&gt;
&lt;p&gt;
  Open up person_spec.rb in textmate or your text editor of choice and let's write our first spec.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200988.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Run 'rake spec' in terminal, and you should get back the response of "1 example, 0 failures". Congratulations. :)
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Time for some test driven development.&lt;/strong&gt; We have decided that every person should have a first_name and last_name. (No use in having a person without one). Let's write two specs to test for this. They should both fail.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200990.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Run 'rake spec', and you should receive the response back '3 examples, 2 failures'. Open up the person.rb model and add the validates_presence_of.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200991.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Run 'rake spec' again, and you should receive the response back '3 examples, 0 failures'. Nice work, you just did test driven development.
&lt;/p&gt;
&lt;p&gt;
  Next let's refactor things slightly using our spec_helper.rb to store some reusable code. This is optional and isn't so useful with such a small suite of tests, but once your test count climbs to 50 or more it is really nice to have a setup similar to the following. It basically uses helper methods inside of spec_helper.rb (which is being required with the line 'require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')').
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;person_spec.rb&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/200999.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;spec_helper.rb&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201000.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Good work. You've written a few model tests to test your person.rb model pretty well. Let's move on to integration testing.
&lt;/p&gt;
&lt;h3&gt;Integration testing&lt;/h3&gt;
&lt;p&gt;
  Before I demonstrate integration testing, let me say that many programmers test their views, helpers, and controllers separately. This is not smart and if you are doing that you should stop. Take Merb's testing approach as an example. Merb's testing framework encourages the developer to test the final http response rather than worry about testing your views, controllers, and helpers separately. Afterall, these three items are working together to create the final http response. It makes a lot of sense and saves a lot of time. (Yehuda Katz can tell you more about this in his &lt;a href="http://video.merbcamp.com/public/katz1.mp4"&gt;video on merb testing&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
  Rails doesn't have Merb's fancy response testing, but it does have integration testing using the powerful webrat. (Cucumber uses Webrat - which is about the only thing I like about cucumber.)
&lt;/p&gt;
&lt;h4&gt;
  Setup
&lt;/h4&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201540.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Add config.gem 'webrat' to your config/environments/test.rb file
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201547.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Open up spec_helper.rb and add the webrat configure block.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201542.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Create the spec/integration folder and file
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201543.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h4&gt;
  Write the integration test
&lt;/h4&gt;
&lt;p&gt;
  Now you are ready to write your first integration test using webrat. We are going to test some basics from the people scaffold we created. Edit spec/integration/people_spec.rb, make it look like the following, and run 'rake spec' again. You should receive the response back '5 examples, 0 failures'.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201548.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h4&gt;
  What is going on here?
&lt;/h4&gt;
&lt;p&gt;
  The majority of the above code is your standard rspec (before(:each) blocks, describe blocks, it "should do something" blocks, etc). The webrat methods we are using are 'visit' and 'response'.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;visit&lt;/strong&gt; simulates an actual user visiting your website. You don't see it happen, but webrat is actually (sort of) visiting the site just like a normal user would in their browser. To visit other pages just do visit '/your/path'.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;After the visit command is employed, webrat returns a response&lt;/strong&gt; from the webpage. This is essentially the http response a visitor's browser would receive. Here we are checking the response.status to verify it returned a 200 OK. To inspect the available response options use 'puts response.inspect'.
&lt;/p&gt;
&lt;p&gt;
  Now let's test that the response contains certain text. You can use webrat's have_selector or have_xpath methods to determine this. In fact, most of the time with webrat those are the methods you will be using in conjunction with visit and response. Let's check that the people/new page contains the correct form fields.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201562.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Depending on how you built your scaffold all these tests will pass or you might get 2 failures back. I got two failures. Let's fix those two errors by adding the appropriate form fields to our views/people/new.html.erb file. It should look something like the following.
&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/201563.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Great work. You've already created 8 specs to test your application. Now just repeat the process while consulting the &lt;a href="http://rspec.rubyforge.org/rspec/1.2.8/"&gt;rspec docs&lt;/a&gt; andthe &lt;a href="http://gitrdoc.com/brynary/webrat/tree/master"&gt;webrat docs&lt;/a&gt;, and &lt;strong&gt;before you know it you will find testing a joy and a valuable addition to your programming knowledge&lt;/strong&gt;. Good luck, and you should follow me on twitter &lt;a href="http://twitter.com/spitfiresky"&gt;here&lt;/a&gt; if you have questions.
&lt;/p&gt;
&lt;p&gt;
  Also, the example app I built along with this tutorial is &lt;a href="http://github.com/scottmotte/people"&gt;here on github&lt;/a&gt;.
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/how-you-should-be-doing-testing-in-rails.html</feedburner:origLink></entry>
  
  <entry>
    <title>Sdruby Presentation on Titanium-Mobile</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/tk3V9PU3v6A/sdruby-presentation-on-titanium-mobile.html" />
    <id>tag:spitfiresky.com,Mon Sep 07 09:37:28 -0700 2009:1252341448</id>
    <updated>Mon Sep 07 09:37:28 -0700 2009</updated>
    <content type="html">&lt;h2&gt;Sdruby Presentation on Titanium-Mobile&lt;/h2&gt;
&lt;p&gt;Here are my slides from my sdruby presentation on &lt;a href="http://www.appcelerator.com/products/titanium-mobile/"&gt;Titanium Mobile&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Slides&lt;/h3&gt;
&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=titanium-mobile-090907113638-phpapp01&amp;stripped_title=titanium-mobile" /&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=titanium-mobile-090907113638-phpapp01&amp;stripped_title=titanium-mobile" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
For this presentation I covered getting started with Titanium mobile. Plus, I included example javascript code from the app I am currently building.
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/sdruby-presentation-on-titanium-mobile.html</feedburner:origLink></entry>
  
  <entry>
    <title>Counter Caching with MongoMapper</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/BooR-zrCD8Y/caching-with-mongomapper.html" />
    <id>tag:spitfiresky.com,Sat Aug 29 00:11:46 -0700 2009:1251529906</id>
    <updated>Sat Aug 29 00:11:46 -0700 2009</updated>
    <content type="html">&lt;h2&gt;Counter Caching with MongoMapper&lt;/h2&gt;
&lt;p&gt;MongoMapper makes column based counter caching simple. I think you'll be delighted.&lt;/p&gt;
&lt;h3&gt;What is counter caching?&lt;/h3&gt;
&lt;p&gt;Counter caching is a way to display the record count (or total - using the term loosely) for a has_many assocation. Ryan Bates did a screencast on &lt;a href="http://railscasts.com/episodes/23-counter-cache-column"&gt;it&lt;/a&gt; and many apps today employ counter caching. &lt;small&gt;(aside: You should be doing things like counter caching before you just go and grab memcache.)&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;For example, I am building an application that keeps track of pilots' flights. A pilot is able to log their flights, and the application returns their total flights count. At first I displayed this value using Flight.count(:user_id =&gt; id) in the view. This was ok at first, but once a pilot had one thousand flights, page load times were noticeably longer so I added a counter cache column.&lt;/p&gt;
&lt;p&gt;Counter caching works well. I received some significant speed improvements.&lt;/p&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/177422.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;Ok, let's get on it with it.&lt;/p&gt;
&lt;h3&gt;How to setup counter caching in MongoMapper&lt;/h3&gt;
&lt;h4&gt;Scenario&lt;/h4&gt;
&lt;p&gt;I want to store the sum of a column in a cache. In my application a User has many Flights, and each flight has fields like hours, landings, night_hours, etc. I want to have methods like @user.total_hours, @user.total_landings, and @user.total_night_hours that cache themselves so my app can get similar speed advantages like you saw above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To do this, I:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Added @user.total_something instance methods to my User model.&lt;/li&gt;
  &lt;li&gt;Added callbacks in my Flight model to clear the cache whenever the pilot adds/updates/destroys a flight.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Step #1: Add the instance methods to User.rb&lt;/h4&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/177426.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h4&gt;Step #2: Add the clear cache callbacks to Flight.rb&lt;/h4&gt;
&lt;p&gt;
  &lt;script src="http://gist.github.com/177427.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;That's it. You're done. You can now use @user.total_hours, @user.total_landings, etc in your views and your app will stay snappy.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Counter caching with MongoMapper ended up being just 14 lines of code. You don't have to hassle with migrations and you can meta-program your schema into the model. &lt;small&gt;(Thanks to John Nunemaker for building it that way. Thought: I really don't like the way ActiveRecord uses migrations. Plus, it decouples the schema from the model.)&lt;/small&gt;. It works with floating point numbers too.&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    Keep updated at
    &lt;a href='http://twitter.com/spitfiresky'&gt;twitter.com/spitfiresky&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/caching-with-mongomapper.html</feedburner:origLink></entry>
  
  <entry>
    <title>Recap of my sdruby presentation on mongodb</title>
    <link href="http://feedproxy.google.com/~r/spitfiresky/~3/G2ykitBZTLQ/recap-of-my-sdruby-presentation-on-mongodb.html" />
    <id>tag:spitfiresky.com,Fri Aug 07 09:30:06 -0700 2009:1249662606</id>
    <updated>Fri Aug 07 09:30:06 -0700 2009</updated>
    <content type="html">&lt;h2&gt;Recap of my sdruby presentation on mongodb&lt;/h2&gt;
&lt;p&gt;Here I recap my presentation on mongodb at sdruby last night.&lt;/p&gt;
&lt;h3&gt;Slides&lt;/h3&gt;
&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mongodb-090806212433-phpapp01&amp;stripped_title=mongodb-1825613" /&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=mongodb-090806212433-phpapp01&amp;stripped_title=mongodb-1825613" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I am using mongodb on &lt;a href="http://staging.twinstang.com"&gt;Twinstang redesigned&lt;/a&gt;. &lt;strong&gt;I started with couchdb, but encountered difficulties grasping the concept of map/reduce&lt;/strong&gt; for more powerful but necessary querying.&lt;/p&gt;
&lt;p&gt;Because of this limitation in my skills (and partially because couchdb is limited to doing map/reduce on your documents and cannot do an additional map/reduce on top of a previous map/reduce) I began running into barriers in development of features for my app, and I foresaw more issues on the way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I switched to mongodb using MongoMapper and have been super satisfied.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Dynamic queries are a welcome return&lt;/li&gt;
  &lt;li&gt;There is a good balance of speed, features, and schema-less freedom&lt;/li&gt;
  &lt;li&gt;It should scale better than mysql with less effort&lt;/li&gt;
  &lt;li&gt;MongoMapper makes it a pleasure to work with&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Installation &amp; Running it&lt;/h3&gt;
&lt;p&gt;Installation of mongodb is from source but is quick and painless. After installation type sudo mongod run to run mongodb. You will probably want to use something like monit or god to monitor the process.&lt;/p&gt;
&lt;script src="http://gist.github.com/164002.js"&gt;&lt;/script&gt;
&lt;h3&gt;Mongo vs Couch&lt;/h3&gt;
&lt;p&gt;Couchdb is really cool and I can't say enough how much I've enjoyed it - especially the concepts it is pushing. It has huge potential to open up applications to the masses with its embedded apps. It is essentially a framework and server rolled into one. And it has convinced me that the language of the future is javascript. Furthermore, it's idea to run apps in the browser locally and then replicate/sync is mouthwatering. There are a lot of promises and hopes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;However, map/reduce is difficult to grasp and couchdb's map/reduce feels like a neutered version&lt;/strong&gt;. How come I can't do map/reduces on already built design documents? In the end, couchdb left me somewhat disappointed. It was wrong for my app but was so exciting. I will be using couchdb in the future to build simple api based web apps that users can hook into.&lt;/p&gt;
&lt;p&gt;Mongodb on the other hand feels more traditional. It is not trying to shake things up. Instead, &lt;strong&gt;Mongodb accomplishes its main goal very well&lt;/strong&gt; - to bridge the gap between key/value stores and sql databases. It's fast, is focused on solving scaling issues that have haunted mysql, and it maintains the ease of use and power of dynamic queries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use mongodb for your traditional web app - where your users are doing a lot of updates but where you are generally controlling the interface and features.&lt;/strong&gt; Use couchdb for focused web apps that are mostly an api or web hook and where your users are controlling the interface.&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;strong&gt;Mongodb (C++)&lt;/strong&gt;&lt;/td&gt;
    &lt;td&gt;&lt;strong&gt;Couchdb (Erlang)&lt;/strong&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;drivers &lt;small&gt;(php driver, ruby, python, and more)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;REST &lt;small&gt;(very cool, but slightly slower. not really slower in practice though - except when it comes to replication as a tool to scale)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;bson, document, schema-free&lt;/td&gt;
    &lt;td&gt;json, document, schema-free&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Dynamic queries, indexing &lt;small&gt;(familiar, and great for development time. it works.)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;map/reduce &lt;small&gt;(needs a way to do map/reduce on a design document - essentially a map/reduce on top of a map/reduce)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;gridfs &lt;small&gt;(needs an nginx/apache module. using send_data through an app or even through rack is too slow. however, supposed to be comparative to S3 if a module becomes available)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;embedded attachments &lt;small&gt;(think email attachments. i really like the way couchdb handles attachments)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;RAM&lt;/td&gt;
    &lt;td&gt;http cache&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Good at the web, faster development time &lt;small&gt;(dynamic queries are what we are used to User.first(:login =&gt; 'jennifer'))&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;Good at the web, slower development time &lt;small&gt;(because of map/reduce and you have to construct all your queries from javascript)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Update in place &lt;small&gt;(good for high update rates)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;MVCC &lt;small&gt;(fault tolerant, but requires compacting.)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;master-master &lt;small&gt;(auto-sharding is under development and planned. which should make things quite easy to scale. *thanks Mark)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;replication &lt;small&gt;(great for peer shared apps, but will be slow for large traditional web app databases replicating across servers - it's http)&lt;/small&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;50s kid &lt;small&gt;(Traditional, yet rock n' roll, fast cars. Feels comfortable yet feels like the future. good for traditional web apps)&lt;/small&gt;&lt;/td&gt;
    &lt;td&gt;indy kid &lt;small&gt;(Untraditional, crazy cool ideas (like embedded apps and running in your browser), but uncertain. better for untraditional web apps right now)&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;h3&gt;Mongodb orms&lt;/h3&gt;
&lt;p&gt;If you are a rubyist use &lt;a href="http://github.com/jnunemaker/mongomapper"&gt;MongoMapper&lt;/a&gt;. Hands down it's the best orm. It basically makes the driver easy to use and familiar with rails/merb.&lt;/p&gt;
&lt;h3&gt;Using MongoMapper&lt;/h3&gt;
&lt;h4&gt;Installation&lt;/h4&gt;
&lt;p&gt;sudo gem install mongomapper&lt;/p&gt;
&lt;p&gt;config.gem 'jnunemaker-mongomapper'&lt;/p&gt;
&lt;p&gt;dependency 'jnunemaker-mongomapper'&lt;/p&gt;
&lt;h4&gt;Model&lt;/h4&gt;
&lt;script src="http://gist.github.com/164028.js"&gt;&lt;/script&gt;
&lt;h4&gt;Controller&lt;/h4&gt;
&lt;script src="http://gist.github.com/164033.js"&gt;&lt;/script&gt;
&lt;h4&gt;Validations&lt;/h4&gt;
&lt;script src="http://gist.github.com/164035.js"&gt;&lt;/script&gt;
&lt;h4&gt;Callbacks&lt;/h4&gt;
&lt;script src="http://gist.github.com/164036.js"&gt;&lt;/script&gt;
&lt;h4&gt;Relationships&lt;/h4&gt;
&lt;script src="http://gist.github.com/164038.js"&gt;&lt;/script&gt;
&lt;h4&gt;Embedded Documents&lt;/h4&gt;
&lt;script src="http://gist.github.com/164040.js"&gt;&lt;/script&gt;
&lt;h4&gt;Additional info&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;created_at and updated_at are included automatically by MongoMapper&lt;/li&gt;
  &lt;li&gt;_id cannot currently be set with MongoMapper like it can in Couchrest&lt;/li&gt;
  &lt;li&gt;cannot currently do @doc[‘custom_field’] like in couchrest.&lt;/li&gt;
  &lt;li&gt;indexing: @doc.ensure_index :login&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Overall, I think mongodb with mongomapper is a smart way to go for a traditional web apps that are somewhat complicated (think facebook, basecamp, social networks) where you are providing an interface for your users to put information and then doing all kinds of things with that information.&lt;/p&gt;
&lt;p&gt;I think couchdb is more suited to simple applications with express purposes (think blogs, a 'twitter' of your friends, apis) and where replicating that data from computer to computer and going offline is important.&lt;/p&gt;
&lt;p class='followme'&gt;
  &lt;strong&gt;
    You should follow me on twitter
    &lt;a href='http://twitter.com/spitfiresky'&gt;here&lt;/a&gt;
  &lt;/strong&gt;
&lt;/p&gt;
&lt;br /&gt;
</content>
  <feedburner:origLink>http://spitfiresky.com/blog/recap-of-my-sdruby-presentation-on-mongodb.html</feedburner:origLink></entry>
  
</feed>

