<?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" xml:lang="en-US">
  <id>tag:blog.crowdint.com,2005:/atom</id>
  <link rel="alternate" type="text/html" href="http://blog.crowdint.com" />
  
  <title>Crowd Interactive Tech Blog</title>
  <updated>2013-05-17T16:51:12Z</updated>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CrowdInteractiveTechBlog" /><feedburner:info uri="crowdinteractivetechblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <id>tag:blog.crowdint.com,2005:Post/179</id>
    <published>2013-05-09T16:11:55Z</published>
    <updated>2013-05-17T16:51:12Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/S4oWhWnUeVE/android-builds-on-travis-ci-with-maven.html" />
    <title>Android Builds on Travis CI with Maven</title>
    <content type="html">&lt;p&gt;The Android SDK includes a flavour of &lt;a href="http://developer.android.com/tools/testing/testing_android.html"&gt;JUnit&lt;/a&gt; that supports unit tests and instrumentation tests. This is sufficient if you are coding alone, but working in teams is a different matter. If you want to maintain a healthy master branch of your project whilst working in a fast paced and agile development process, you need tools that automate your application builds and test each change that is introduced in the project.&lt;/p&gt;

&lt;p&gt;We rely on &lt;a href="https://travis-ci.org/"&gt;Travis CI&lt;/a&gt; to build and test web applications. Hence, we wanted to harness our current CI service for Android applications as well.&lt;/p&gt;

&lt;p&gt;After a quick web search, we found this great &lt;a href="http://rkistner.github.io/android/2013/02/05/android-builds-on-travis-ci/"&gt;blog post&lt;/a&gt; that helped us to make some configuration experiments with &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;. This was a nice starting point, but we felt some details were left apart, specially if you have no experience with Maven.&lt;/p&gt;

&lt;p&gt;Therefore, we prepared this post as a step-by-step guide to get you started quickly with Maven and explain some changes to the Android application structure.&lt;/p&gt;

&lt;h3&gt;Requirements&lt;/h3&gt;

&lt;p&gt;Basically, you need to do 3 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the structure of your Android Project.&lt;/li&gt;
&lt;li&gt;The building tools (Maven, Android Maven Plugin, Android SDK).&lt;/li&gt;
&lt;li&gt;Configure a &amp;#39;travis.yml&amp;#39; file to make it work on Travis CI.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Step 1: Application structure&lt;/h3&gt;

&lt;p&gt;You have to change the directory structure of your Android application to comply with the structure shown below.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Project-parent-folder:
   -Android-Application-folder
      -pom.xml
   -Android-Tests-folder
      -pom.xml
   -Android-library-project-folder
      -pom.xml
   -pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;NOTES:&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;We assume you are using the Eclipse IDE.&lt;/li&gt;
&lt;li&gt;If you already have the project in your Eclipse Workspace, you will need to delete it from your workspace and re-import it again (after you change the structure).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Step 2: MAVEN&lt;/h3&gt;

&lt;p&gt;Download &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; and extract the distribution archive to the directory in which you want to install Maven (e.g. apache-maven-3.0.5-bin.tar.gz).&lt;/p&gt;

&lt;p&gt;Supossing you extracted the archive on your $HOME directory, then run on your terminal:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export M2_HOME=$HOME/apache-maven-3.0.5
export M2=$M2_HOME/bin
export PATH=$PATH:$M2
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To verify that it is correctly installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn --version
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Step 3: Eclipse Maven Android Plugin&lt;/h3&gt;

&lt;p&gt;You have to install a plugin to make the Android project work with Maven within Eclipse.&lt;/p&gt;

&lt;p&gt;In Eclipse, go to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;quot;Help&amp;quot; &amp;gt; &amp;quot;Eclipse Marketplace&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you are using Eclipse ADT or do not have the Eclipse Marketplace, install it from:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;quot;Help&amp;quot; &amp;gt; &amp;quot;Install new Software&amp;quot; &amp;gt; &amp;quot;Switch to the Juno Repository&amp;quot; &amp;gt;
&amp;quot;General Purpose Tools&amp;quot; &amp;gt; &amp;quot;Marketplace Client&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;Once in Eclipse MarketPlace:&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Search for:  android m2e&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://rgladwell.github.io/m2e-android/"&gt;Android Configurator for M2E&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Step 4: Eclipse Maven Android Project&lt;/h3&gt;

&lt;p&gt;To make Eclipse detect the project dependencies, you have to convert the Android and dependent Android Library projects to Maven:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Right click on each project:

&lt;ul&gt;
&lt;li&gt;&amp;quot;Maven&amp;quot; &amp;gt; &amp;quot;Convert to Maven project&amp;quot;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Right click on your Android project, 

&lt;ul&gt;
&lt;li&gt;&amp;quot;Maven&amp;quot; &amp;gt; &amp;quot;Update Project&amp;quot;&lt;/li&gt;
&lt;li&gt;Select the related projects and accept the changes.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This should get rid of any Eclipse error about some dependencies not found.&lt;/p&gt;

&lt;p&gt;Also, you have to configure the &amp;#39;pom.xml&amp;#39; files for each project. You can adapt these samples according to your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/pestrada/5568772"&gt;POM file for the Project parent folder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://gist.github.com/pestrada/5568848"&gt;POM file for the Application folder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/pestrada/5568976"&gt;POM file for the Tests project folder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/pestrada/5568917"&gt;POM file for an Android library project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Step 5: Install Maven Android SDK Deployer&lt;/h3&gt;

&lt;p&gt;If you want to avoid the pain of configuring the Android SDKs in your local Maven repositories, this tool is a must.&lt;/p&gt;

&lt;p&gt;Once you run this on your terminal, you will have all the Android SDK available as Maven dependencies.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone https://github.com/mosabua/maven-android-sdk-deployer.git
cd android-sdk-deployer
mvn install
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Step 6: Install External Android Library Projects&lt;/h3&gt;

&lt;p&gt;If you are using any Android library project, you have to perform some additional steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compress the &amp;quot;library&amp;quot; folder of each library project and change the extension of the file to &amp;#39;.apklib&amp;#39;&lt;/li&gt;
&lt;li&gt;The .apklib files should be put in your Application &amp;#39;libs&amp;#39; folder (e.g. AndroidProject/libs)&lt;/li&gt;
&lt;li&gt;Install each library on your local maven repository, as follows:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run on your terminal, from your Android Application Project&amp;#39;s root folder:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn install:install-file \
-Dfile=libs/your-library-file-1.apklib \
-DgroupId=com.your-library-package \
-DartifactId=your-library-artifact-id \
-Dversion=1 \
-Dpackaging=apklib
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Step 7: Installing and deploying the application&lt;/h3&gt;

&lt;p&gt;These commands are for building the application and deploying to a device.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn clean install
mvn android:deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Step 8: Running Tests&lt;/h3&gt;

&lt;p&gt;On the Emulator:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn clean install -Pintegration-tests -Dandroid.device=your_emulator_name
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;on the Device:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mvn clean install -Pintegration-tests -Dandroid.device=usb
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Step 9: Travis CI configuration&lt;/h3&gt;

&lt;p&gt;If everything works as it should in your local environment, then, all you need is to add a &amp;#39;.travis.yml&amp;#39; file to your application.&lt;/p&gt;

&lt;p&gt;This is an example of the configuration we are using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;language: java
jdk: oraclejdk7
env:
 matrix:
   # android-16 is always included
   - ANDROID_SDKS=sysimg-16           ANDROID_TARGET=android-16  ANDROID_ABI=armeabi-v7a
   - ANDROID_SDKS=android-17,sysimg-17 ANDROID_TARGET=android-17  ANDROID_ABI=armeabi-v7a
before_install:
  # Install base Android SDK
  - sudo apt-get update -qq
  - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch &amp;gt; /dev/null; fi
  - wget http://dl.google.com/android/android-sdk_r21.1-linux.tgz
  - tar xzf android-sdk_r21.1-linux.tgz
  - export ANDROID_HOME=$PWD/android-sdk-linux
  - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools

  # Install required components.
  # For a full list, run `android list sdk -a --extended`
  # Note that sysimg-16 downloads the ARM, x86 and MIPS images (we should optimize this).
  # Other relevant API&amp;#39;s:
  #  addon-google_apis-google-16
  - android update sdk --filter platform-tools,android-16,extra-android-support,66,$ANDROID_SDKS --no-ui --force &amp;gt; /dev/null

  # Create and start emulator
  - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
  - emulator -avd test -no-skin -no-audio -no-window &amp;amp;

before_script:
  - chmod +x wait_for_emulator
  - ./wait_for_emulator

script: mvn install -Pintegration-tests -Dandroid.device=test
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, note that we use the &amp;#39;wait-for-emulator&amp;#39; script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash

bootanim=&amp;quot;&amp;quot;
failcounter=0
until [[ &amp;quot;$bootanim&amp;quot; =~ &amp;quot;stopped&amp;quot; ]]; do
   bootanim=`adb -e shell getprop init.svc.bootanim 2&amp;gt;&amp;amp;1`
   echo &amp;quot;$bootanim&amp;quot;
   if [[ &amp;quot;$bootanim&amp;quot; =~ &amp;quot;not found&amp;quot; ]]; then
      let &amp;quot;failcounter += 1&amp;quot;
      if [[ $failcounter -gt 3 ]]; then
        echo &amp;quot;Failed to start emulator&amp;quot;
        exit 1
      fi
   fi
   sleep 1
done
echo &amp;quot;Done&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both the Travis configuration file and Wait-for-emulator script were adapted from this &lt;a href="https://github.com/embarkmobile/android-maven-example"&gt;Maven Android Example&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Finally&lt;/h3&gt;

&lt;p&gt;Push some changes to your Github repository (you need to have the Travis hook activated) and you should see that Travis builds and tests your Android application. Nice!&lt;/p&gt;

&lt;h3&gt;References&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.google.com/p/maven-android-plugin/"&gt;Android Maven Plugin Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rkistner.github.io/android/2013/02/05/android-builds-on-travis-ci/"&gt;Kistner&amp;#39;s Android builds blogpost&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out &lt;a href="http://www.magmaconf.com/"&gt;MagmaConf&lt;/a&gt;, our very own international conference for Ruby specialists, coming soon in Mexico!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/S4oWhWnUeVE" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/b07554b05ba6bf78ffed784fef5c496d.png?r=PG</photo>
    <author>
      <name>Paul Estrada</name>
      <email>paul.estrada@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/05/17/android-builds-on-travis-ci-with-maven.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/167</id>
    <published>2013-03-19T05:23:50Z</published>
    <updated>2013-05-10T18:10:03Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/y9Sf6ONazEE/bye-google-reader.html" />
    <title>Bye Google Reader</title>
    <content type="html">&lt;p&gt;A couple of days ago I got up in the morning and, as usual, my laptop was on, I sat comfortably in front of my computer and headed to the one I visit first,  &lt;a href="http://reader.google.com"&gt;Google Reader&lt;/a&gt;, but:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/111/googreadershutdown_616.jpg" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;That box appeared over my precious feeds, my dismay was great when I received the bitter news from the hands of Google, the company I trust my personal information, my digital life. That menacing box marked &amp;quot;Google Reader will not be available after July 1, 2013&amp;quot; and a simple blue button with no other choice but &amp;quot;OK&amp;quot;, I clicked the button and the box disappeared, but that feeling of discomfort and uncertainty did not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back in 2005&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Doing some research, it didn&amp;#39;t  take long to learn from Google&amp;#39;s official blog, that as part of a &lt;a href="http://googleblog.blogspot.mx/2013/03/a-second-spring-of-cleaning.html"&gt;Second Spring Cleaning&lt;/a&gt;, Google Reader (among other products) will be gone by the first of July this year.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://img.routledgeweb.com/site/rss/rojologo.jpg" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;It is a rare feeling, like being kicked out of your own house, where you spend a lot of time, and you have grown accustomed to, I had started using Google Reader shortly after its launch in 2005, before that I used another service called Rojo, which offered functionality comparable to Google Reader. At that time Rojo was the best (in my humble opinion) way to read feeds in 2006. But when the Google app hit the market , of course I had to try it. I loved it and I stayed with it for more than six years, watching it evolve into the product it became to be. But in recent months, it seemed lacking in features... maybe that was a sign of what laid ahead, I did not see it coming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternatives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I started reviewing my options to continue reading my feeds. I thought of finding a desktop application, but none of the ones I&amp;#39;ve tried ever convinced me. The idea of having all my feeds in a single place, available and synced to use in all of my devices, was something I was never ready to give up. Many sites have listed alternative to Google Reader, but the one from &lt;a href="http://lifehacker.com/5990881/five-best-google-reader-alternatives"&gt;lifehacker&lt;/a&gt; stands over the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abandon Ship&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, I started packing up and getting ready to move one. The first step before leaving Google Reader is taking with you your highly valued feed list, with that would be enough, but if you are worried about your followers, people you follow, favorites, among other things , Google offers a service that seems effective, this is called Google Takeout, an gets your &amp;quot;luggage&amp;quot; ready  for you. It can be found withing your  Reader settings, in the import tab / export.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/115/importexport.png" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;Google Takeout generates a zip file with the selected services, in this scenario with the Google Reader files, among the files you can find in the package we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Followers&lt;/li&gt;
&lt;li&gt;Followed&lt;/li&gt;
&lt;li&gt;Liked&lt;/li&gt;
&lt;li&gt;Notes&lt;/li&gt;
&lt;li&gt;Shared&lt;/li&gt;
&lt;li&gt;Shared by Followers&lt;/li&gt;
&lt;li&gt;Starred&lt;/li&gt;
&lt;li&gt;Subscriptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in standard formats such as JSON and XML. And well, with suitcases in hand, it&amp;#39;s time to choose a new home.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feedly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many authors agree, and rightly so, that Feedly is one of the best, or the best alternative to Reader in the current app market, but in my opinion it is a little overloaded with eye candy, but it works well enough. The navigation is through shortcuts like Reader, and it has different layouts for different content you may have in your feeds.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/114/feedly.png" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;Currently, Feedly lets you import all your feeds from Google Reader, you just have to grant permission to a third-party application, it is not necessary to do the import of your feeds, but it&amp;#39;s always a good idea to have your feeds backed up in an XML file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I will continue using Google Reader to the last day, although I&amp;#39;m already using Feedly as a new reader. Sounds like a bad move and I resent Google&amp;#39;s decision to terminate Reader, but this will give room for new products and new ideas from development enthusiasts to come to the scene.&lt;/p&gt;

&lt;p&gt;Thanks for reading, looking forward to see your comments!&lt;/p&gt;

&lt;p&gt;And, see you at &lt;a href="http://www.magmaconf.com/"&gt;MagmaConf!&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/y9Sf6ONazEE" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/9d2d73612dcc5c42fa0ae4540002a77c.png?r=PG</photo>
    <author>
      <name>Edmundo Perez</name>
      <email>edmundo.perez@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/05/10/bye-google-reader.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/178</id>
    <published>2013-04-29T23:37:43Z</published>
    <updated>2013-05-06T22:40:53Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/0OMVT9AhjBo/railsconf-2013-schedule-app-unofficial.html" />
    <title>RailsConf 2013 Schedule App, unofficial</title>
    <content type="html">&lt;p&gt;Last Friday(04/27) a few co-workers and I were reviewing the &lt;a href="http://www.railsconf.com/2013/talks"&gt;RailsConf 2013 program&lt;/a&gt; and I found that it was very hard to see the schedule on my phone&amp;#39;s small screen.  When I tried to create a calendar of the talks I wanted to attend, I noticed that it wasn&amp;#39;t possible.&lt;/p&gt;

&lt;p&gt;The RailsConf site has a fixed width, so it&amp;#39;s not easy to read on the small screen, so I thought - &amp;quot;there has to be an app for this&amp;quot;. First I thought that I should contact the RailsConf organizers and make my request, then just sit and wait for the answer. That probably would have been easier, but then I thought to myself:  &amp;quot;Wait a minute!, I&amp;#39;m a web developer, I build applications everyday, I write code, I know how to do it, I know how to write responsive CSS&amp;quot;.  So I decided to build this app.&lt;/p&gt;

&lt;p&gt;Building the app sounds like a straightforward process, but it has a couple of complications, starting with the fact that I didn&amp;#39;t have the program data, I tried inspecting the RailsConf Site&amp;#39;s code looking for a JSON call or something similar, but I found nothing. I started to worry about it, because I really wanted to do this, but without the data it would be useless.  Then one of my friends said joking: &amp;quot;you could perform a screen scrapping&amp;quot;.  That&amp;#39;s a crazy idea; but it might work, I thought. &lt;/p&gt;

&lt;p&gt;Then I remembered a &lt;a href="http://blog.crowdint.com/2013/01/29/how-to-get-what-you-need-with-nokogiri.html"&gt;post about screen scrapping&lt;/a&gt; so I went to Eduardo and asked him to do the scrapping and to provide me of a JSON with the data, which he did in a few minutes.&lt;/p&gt;

&lt;p&gt;So now I &lt;a href="https://github.com/efigarolam/railsconf_schedule_to_json"&gt;have the JSON&lt;/a&gt;, and I just need to write the app to show the data.&lt;/p&gt;

&lt;p&gt;I was there, creating my rails new and I really wanted to make something useful for me and everybody, and also to make it look good. I&amp;#39;m tired of Twitter&amp;#39;s Bootstrap, &amp;#39;cause now the internet looks all the same; so I found this new front-end framework which came very handy &lt;a href="http://gumbyframework.com/"&gt;Gumby 2&lt;/a&gt;. It&amp;#39;s really simple to use and it&amp;#39;s written in Sass, which I love.&lt;/p&gt;

&lt;p&gt;I wrote this is app this past Saturday and between Airports and Airplanes, fixed a couple of bugs during my trip to Portland, OR. &lt;/p&gt;

&lt;h4&gt;Stop talking and show me the app!&lt;/h4&gt;

&lt;p&gt;just go to 
&lt;a href="http://railsconfschedule.com/"&gt;http://railsconfschedule.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/121/Screen_Shot_2013-04-30_at_1.26.51_AM.png" alt="image alt"&gt;&lt;/p&gt;

&lt;h4&gt;Features?&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;It is a really simple app, it loads the data from of couple of JSONs and displays them nicely on the page.&lt;/li&gt;
&lt;li&gt;It uses Omnioauth Authentication with Github as strategy.&lt;/li&gt;
&lt;li&gt;You can build your day-by-day schedule. Add and Remove talks. &lt;/li&gt;
&lt;li&gt;it is responsive, it looks beautiful in your phone, it actually looks better than the bigger screen, I think. ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/122/Screen_Shot_2013-04-30_at_1.27.46_AM.png" alt="image alt"&gt;&lt;/p&gt;

&lt;h5&gt;TODO:&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Show Talk description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import to Google Calendar.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;RailsConf now has an app, is it worth it?&lt;/h4&gt;

&lt;p&gt;It&amp;#39;s totally worth it, I&amp;#39;ve build and app in just a day, I&amp;#39;m using it for managing my own schedule, and I have some pull request from a couple of friends who would like to help to make this better. And It was really fun.&lt;/p&gt;

&lt;h4&gt;Please Contribute&lt;/h4&gt;

&lt;p&gt;No matter if you think that the app is good or not, contribute to make it better! Fork the repo, hack a little bit and make it better!. Submit your pull request and help us with this project.&lt;/p&gt;

&lt;p&gt;If you have never performed a pull request, I highly encourage you to go for this one, you could continue helping other projects after this, and the community will be thankful. It doesn&amp;#39;t matter if you only fix a typo, or a security loophole... just go ahead and contribute.&lt;/p&gt;

&lt;p&gt;Yo can find the code at &lt;a href="https://github.com/hecbuma/railsconf/"&gt;https://github.com/hecbuma/railsconf/&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Final words&lt;/h4&gt;

&lt;p&gt;If you identify a problem, and you have the tools and knowledge to solve it, go ahead and fix it!. You will be helping everyone. You may think that the problem is too simple to merit your contribution, but  your work could be a lifesaver to the rest of us. &lt;/p&gt;

&lt;p&gt;I hope you enjoy this app!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/0OMVT9AhjBo" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/902be69eb9ba93e412129d14010b48bf.png?r=PG</photo>
    <author>
      <name>Hector Bustillos</name>
      <email>hector.bustillos@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/04/30/railsconf-2013-schedule-app-unofficial.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/169</id>
    <published>2013-04-09T18:27:45Z</published>
    <updated>2013-05-06T15:32:23Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/a1dDkwd4dqM/fun-with-activerecord-observer.html" />
    <title>Fun with ActiveRecord::Observer</title>
    <content type="html">&lt;blockquote&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;

&lt;p&gt;ActiveRecord::Observer will be extracted to a separated gem when Rails 4 is released, so if you are planning to upgrade to the latest Rails version and want to use ActiveRecord::Observer, you&amp;#39;ll need to add the rails-observer gem to your Gemfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using ActiveRecord::Observer is a good practice, instead of bloating your model with a lot of callbacks, moving this behavior to another class with only this responsability sounds great, but ActiveRecord::Observer has some &amp;quot;limitations&amp;quot;, I quoted that because they seem like limitations, but the problem is that ActiveRecord::Observer&amp;#39;s capabilities aren&amp;#39;t fully documented or aren&amp;#39;t visible, you have to dig in the source code and figure out how it works.&lt;/p&gt;

&lt;p&gt;By default, ActiveRecord::Observer watched a limited set of callbacks defined by the ActiveRecord::Callbacks::CALLBACKS constant, which are:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/callbacks.rb#L270"&gt;From the rails source&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CALLBACKS = [
  :after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
  :before_save, :around_save, :after_save, :before_create, :around_create,
  :after_create, :before_update, :around_update, :after_update,
  :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But what if you want to add you own callbacks?, is there a way to do that? There surely is one. &lt;/p&gt;

&lt;h2&gt;Adding your own callbacks&lt;/h2&gt;

&lt;p&gt;ActiveRecord::Observer functionality is fairly easy to understand, there is a notify_observers method in the &lt;a href="https://github.com/rails/rails/blob/3-2-stable/activemodel/lib/active_model/observing.rb#L113"&gt;ActiveModel::Observing module&lt;/a&gt; that we can use to define our own callbacks with something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Notifications
  def notify_completed
    notify_observers :after_complete
  end
end

class Action &amp;lt; ActiveRecord::Base
  include Notifications

  def complete!
    ...
    notify_completed
  end
end

class ActionObserver &amp;lt; ActiveRecord::Observer
  def after_complete(action)
    # your callback logic here
    ...
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;#39;s it, you&amp;#39;ll have the after_complete callback available in your observer class, this method will receive the model instance where the callback is triggered as an argument.&lt;/p&gt;

&lt;p&gt;But, what if I want to know more about the event that triggered the callback, not just the instance where it ocurred? Maybe I want to find out more about the user that triggered the action, is there a way to do that?, well, try this. &lt;/p&gt;

&lt;h2&gt;Sending more arguments in the callback&lt;/h2&gt;

&lt;p&gt;If you look in the &lt;a href="https://github.com/rails/rails/blob/3-2-stable/activemodel/lib/active_model/observing.rb#L113"&gt;notify_observers source&lt;/a&gt;, you&amp;#39;ll see that it only receives one argument at a time, but you can see that this method uses a &lt;a href="https://github.com/rails/rails/blob/3-2-stable/activemodel/lib/active_model/observing.rb#L73"&gt;class method with the same name&lt;/a&gt; but this one accepts many arguments. &lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://github.com/rails/rails/blob/3-2-stable/activemodel/lib/active_model/observing.rb#L113"&gt;original notify_observers&lt;/a&gt; they always use self as the second argument, we are going to change that with another object, I&amp;#39;ll use a hash, but you can wrap your arguments into a class, the important thing here is that the second argument needs to be an object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Notifications
  def notify_completed(user)
    self.class.notify_observers :after_complete, { action: self, user: user }
  end
end

class Action &amp;lt; ActiveRecord::Base
  include Notifications

  def complete!(user)
    ...
    notify_completed(user)
  end
end

class YourModelObserver &amp;lt; ActiveRecord::Observer
  def after_complete(event)
    # your callback logic here
        # The event argument will be a Hash with action and user keys.
    ...
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;#39;s it.&lt;/p&gt;

&lt;p&gt;There are many things that Rails can do for you, but you&amp;#39;ll need to go beyond the docs, diving deep in the source is the best way to find those things. &lt;/p&gt;

&lt;p&gt;Hope you find this useful, thanks for reading!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/a1dDkwd4dqM" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/de453538cc7e6047d144995f0ddac38f.png?r=PG</photo>
    <author>
      <name>Herman Moreno</name>
      <email>herman.moreno@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/04/23/fun-with-activerecord-observer.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/170</id>
    <published>2013-04-09T18:33:04Z</published>
    <updated>2013-04-18T18:04:17Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/XalIPoKsM1g/introducing-triggerino-an-arduino-based-action-trigger.html" />
    <title>Introducing Triggerino, an Arduino based action trigger</title>
    <content type="html">&lt;p&gt;First of all, I need to say that I was fully inspired by &lt;a href="http://madewithbytes.com/writting/mercurio-the-deployment-black-box/"&gt;this blogpost&lt;/a&gt;, I liked so much that project, that I decided to fork this project and use Ruby instead of Python. &lt;/p&gt;

&lt;h2&gt;A little bit of history&lt;/h2&gt;

&lt;p&gt;One of the things I&amp;#39;m passionated about is the DIY philosophy, when I was young I used to spend my time doing experiments with electronics, but then I grew up and I replaced that passion with programming.&lt;/p&gt;

&lt;p&gt;In the past RubyConf there was a &lt;a href="http://www.confreaks.com/videos/1294-rubyconf2012-arduino-the-ruby-way"&gt;talk&lt;/a&gt; from &lt;a href="http://iamaust.in/"&gt;Austin Vance&lt;/a&gt; that involved Ruby and Arduino, I must say that was very interesting, that talk woke up my passion with electronics, and the best of all, it mixes both passions.&lt;/p&gt;

&lt;p&gt;That day at the end of the conferences, I went to the closest Radioshack® and I bought my Arduino starter kit, and since then I&amp;#39;ve been experimenting with my Arduino and Ruby, with the time those experiments became Triggerino.&lt;/p&gt;

&lt;h2&gt;What is Triggerino?&lt;/h2&gt;

&lt;p&gt;The main idea of this is to have a box with a big red button, and have the ability of run tasks from my ruby project pushing that button. Cool, isn&amp;#39;t it?&lt;/p&gt;

&lt;h2&gt;What can I do with Triggerino?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run your test suite&lt;/li&gt;
&lt;li&gt;Deploy your project&lt;/li&gt;
&lt;li&gt;Run rake tasks&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;Run whatever you want&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;Add these lines to your application&amp;#39;s Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;#39;triggerino&amp;#39;
gem &amp;#39;dino&amp;#39;,
  git://github.com/supherman/dino.git&amp;#39;,
  branch: &amp;#39;lcdv3&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then execute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Usage&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a &amp;quot;triggerino&amp;quot; dir&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir triggerino
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define your action classes&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;touch triggerino/my_action.rb

class MyAction
  include Triggerino::Action

  def perform
    # puts your action logic here
  end

  def to_s
    &amp;#39;A descriptive name for your action&amp;#39;
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wire your arduino like this:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="http://arduino.cc/es/uploads/Tutorial/lcd_bb.png" alt="LCD"&gt;&lt;/p&gt;

&lt;p&gt;Also add 2 push buttons: one will be the action selector and it needs to be connected to the pin 10, and a the other one will be the trigger and it needs to be connected to the pin 9.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Run the listener&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle exec triggerino
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Need to know more about Arduino and Ruby?&lt;/h2&gt;

&lt;p&gt;Keep and eye on the &lt;a href="https://github.com/austinbv/dino"&gt;dino gem&lt;/a&gt;, people started to contribute on the project and they are doing amazing things that will make work with Arduino and Ruby easier.&lt;/p&gt;

&lt;p&gt;And If you like robots and electronic stuff, you&amp;#39;ll want to take a look at &lt;a href="http://artoo.io/"&gt;Artoo&lt;/a&gt;, a framework that will help you build robots with Ruby, it has support for Arduino, Parrot AR Drone 2.0, Sphero and Roomba.&lt;/p&gt;

&lt;p&gt;Also, if you are a dev with an itch to learn more about this kind of topics, I think you should go to &lt;a href="http://magmaconf.com/"&gt;MagmaConf&lt;/a&gt;, there will be 2 talks about electronics and Ruby; so it will be a good chance to learn something new.&lt;/p&gt;

&lt;p&gt;And that&amp;#39;s it for now, hope you find this useful and interesting. ;)&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/XalIPoKsM1g" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/de453538cc7e6047d144995f0ddac38f.png?r=PG</photo>
    <author>
      <name>Herman Moreno</name>
      <email>herman.moreno@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/04/18/introducing-triggerino-an-arduino-based-action-trigger.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/165</id>
    <published>2013-03-14T16:55:17Z</published>
    <updated>2013-04-05T16:58:46Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/sIbTw0bgwac/templating-with-handlebars.html" />
    <title>Templating with Handlebars</title>
    <content type="html">&lt;h1&gt;Templating with Handlebars&lt;/h1&gt;

&lt;p&gt;Remember that time you started creating your own app for no other reason than just learning, experimenting and having fun?&lt;/p&gt;

&lt;p&gt;It started out as a super simple single-task application. At the beginning you were pretty happy with it, but not much later you realized it was useless, so you decided to extend it a little bit.&lt;/p&gt;

&lt;p&gt;If you are anything like me you probably used a single view (because you&amp;#39;re cool or maybe you were using Backbone) and started putting tons of ajax calls everywhere to load dynamic content.
It didn&amp;#39;t take long until your code turned into a complete mess (with tons of html within your Javascript.. yuck! ).
You probably thought that there must be a better way to do it.. and you were right. Templates are exactly what you need.&lt;/p&gt;

&lt;p&gt;If you do a little research about templating engines for javascript, you will find that there are a lot of them. So which one should you choose? &lt;/p&gt;

&lt;p&gt;Well honestly you could choose any and it will do the work. But if you&amp;#39;re looking for a simple, powerful and fast engine that can work in both simple and complex apps, I will recommend you to try Handlebars.&lt;/p&gt;

&lt;h3&gt;Why Handlebars?&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It uses simple syntax &lt;/li&gt;
&lt;li&gt;It is Easy to use&lt;/li&gt;
&lt;li&gt;It&amp;#39;s fast!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Handlebars&amp;#39; &amp;#39;logic-less&amp;#39; syntax is incredible. It is really simple and easy to read, and it even looks cool. Being easy to read makes it really easy to use too and since the templates can be pre-compiled, Handlebars can go from fast to super-fast.&lt;/p&gt;

&lt;p&gt;Take a look at this minimalistic &lt;strong&gt;example&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;We have a very basic document.&lt;/p&gt;

&lt;script src="https://gist.github.com/iwano/5224465.js"&gt;&lt;/script&gt;
     

&lt;p&gt;You can notice that the document is completely empty. There are just a few lines in the script section (inside the head).
In the first two lines we&amp;#39;re requiring Jquery and Handlebars, and in the third one we&amp;#39;re defining our Handlebars template.&lt;/p&gt;

&lt;p&gt;If you save this file and open it on your browser you&amp;#39;d see, well.. nothing! We did define our template but we&amp;#39;re not using it anywhere.&lt;/p&gt;

&lt;p&gt;Opening the browser&amp;#39;s console and running this lines would give us a different result though.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var source   = $(&amp;quot;#person-template&amp;quot;).html();
var template = Handlebars.compile(source);
var data = {name: &amp;quot;ivan&amp;quot;, email: &amp;quot;iwano@hotmail.com&amp;quot;, city:&amp;quot;Colima&amp;quot;};
var html    = template(data);
$(&amp;#39;body&amp;#39;).append(html);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Congrats! you just created your first Handlebars template :D&lt;/p&gt;

&lt;p&gt;Pretty much all we did was getting the template we defined in the head of our document, compiling it, feeding it with an object to be evaluated, and then appending the output HTML to the body of the document.&lt;/p&gt;

&lt;p&gt;It is no coincidence that the attributes of the object we send to the template match the ones defined in it. 
If our object would have had only a name attribute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var context = {name: &amp;quot;ivan&amp;quot;};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Handlebars would have evaluated only the name attribute and returned nothing for the missing email and city ones:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;person&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;ivan&amp;lt;/h1&amp;gt;
  &amp;lt;h2&amp;gt;&amp;lt;/h2&amp;gt;
  &amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Handlebars you put whatever you want to be evaluated inside 2 sets of keys {{ expression }}.&lt;/p&gt;

&lt;h3&gt;Blocks&lt;/h3&gt;

&lt;p&gt;You can also use blocks in your Handlebars templates. Let&amp;#39;s say we have the following object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var data = { 
  persons:
    [{
       name: &amp;#39;ivan&amp;#39;,
       email: &amp;#39;iwano@hotmail.com&amp;#39;,
       city: &amp;#39;Colima&amp;#39;
    },
    {
       name: &amp;#39;Michael&amp;#39;,
       email: &amp;#39;mscott@dunder.com&amp;#39;,
       city: &amp;#39;Scranton&amp;#39;
    }]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you define your template like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{{#persons}}
   &amp;lt;div class=&amp;quot;person&amp;quot;&amp;gt;
      &amp;lt;h1&amp;gt;{{name}}&amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;{{email}}&amp;lt;/h2&amp;gt;
      &amp;lt;h3&amp;gt;{{city}}&amp;lt;/h3&amp;gt;
   &amp;lt;/div&amp;gt;
{{/persons}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We would get an output like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;person&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;ivan&amp;lt;/h1&amp;gt;
  &amp;lt;h2&amp;gt;iwano@hotmail.com&amp;lt;/h2&amp;gt;
  &amp;lt;h3&amp;gt;Colima&amp;lt;/h3&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;person&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;Michael&amp;lt;/h1&amp;gt;
  &amp;lt;h2&amp;gt;mscott@dunder.com&amp;lt;/h2&amp;gt;
  &amp;lt;h3&amp;gt;Scranton&amp;lt;/h3&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this we can iterate over each of the elements in our collection changing the context towards each of them.&lt;/p&gt;

&lt;p&gt;If our object would happened &lt;strong&gt;not&lt;/strong&gt; to be a collection, this would still work printing the only one item.&lt;/p&gt;

&lt;p&gt;We could have used this as well:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{{#each persons}}
   .
   .
{{/each}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some other blocks you can use:&lt;/p&gt;

&lt;h4&gt;if&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;{{#if email}}
   .
   .
{{/if}}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;unless&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;{{#unless email}}
   .
   .
{{/unless}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;This blocks do exactly what you&amp;#39;d expect.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notice&lt;/strong&gt; that all blocks have an &lt;strong&gt;opening&lt;/strong&gt; and a &lt;strong&gt;closing&lt;/strong&gt; tag.&lt;/p&gt;

&lt;h4&gt;Blocks&lt;/h4&gt;

&lt;p&gt;You can even create your own helpers and use them whenever you want:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Handlebars.registerHelper(&amp;#39;instroduceYourself&amp;#39;, function(person) {
  return &amp;quot;Hi my name is &amp;quot; + person.name + &amp;quot; and i&amp;#39;m from &amp;quot; + person.city + &amp;quot;!&amp;quot;;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To call your brand new helper from inside your template you would do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;#39;introduction&amp;#39;&amp;gt;
  {{instroduceYourself person}}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So you would get something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;#39;introduction&amp;#39;&amp;gt;
  Hi my name is ivan and i&amp;#39;m from Colima!
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You could define the helper whenever you want or even in a separate file (just make sure to include it after including Handlebars!).&lt;/p&gt;

&lt;p&gt;Handlebars HTML-escapes all outputs by default, but you can always change that by using {{{ expression }}} (3 keys), in case (for some reason) you have something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
    name: &amp;#39;&amp;lt;h1&amp;gt;ivan&amp;lt;/h1&amp;gt;&amp;#39;,
    email: &amp;#39;&amp;lt;a href=&amp;#39;mailto:iwano@hotmail.com &amp;gt;ivan&amp;lt;/a&amp;gt;&amp;#39;,
    city: &amp;#39;&amp;lt;h2&amp;gt;Colima&amp;lt;/h2&amp;gt;&amp;#39;
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Handlebars in a Rails/Backbone app&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;d like to use handlebars in your rails/backbone app follow these simple steps:&lt;/p&gt;

&lt;p&gt;in your &lt;strong&gt;Gemfile&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;#39;handlebars_assets&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From your console run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In your application.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;//= require handlebars.runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;#39;s it, you&amp;#39;re ready to create your templates with Handlebars. Just make sure to let your views know that you&amp;#39;ll be using Handlebars by putting &amp;#39;HandlebarsAssets&amp;#39; in your template attribute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;template : HandlebarsTemplates[&amp;#39;backbone/templates/your_template&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Wrapping up&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Templates:&lt;/strong&gt; +1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handlebars:&lt;/strong&gt; +2&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;html-escaped:&lt;/strong&gt;     {{ expression }}&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;html-unescaped:&lt;/strong&gt; {{{ expression }}}&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;helpers:&lt;/strong&gt;               {{ helper_name parameters}}&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;blocks:&lt;/strong&gt;                {{#block&lt;em&gt;name}} . {{/block&lt;/em&gt;name}}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&amp;#39;d like to read more about Handlebars what better place than the official Handlebars&amp;#39; &lt;a href="http://handlebarsjs.com/"&gt;site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you haven&amp;#39;t got your ticket for &lt;a href="http://magmaconf.com/"&gt;MagmaConf 2013&lt;/a&gt; (if you have it you rock!) what are you waiting for!&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/sIbTw0bgwac" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/fab96d836ba93f9e09ecd8cafd225844.png?r=PG</photo>
    <author>
      <name>Iván Calderón</name>
      <email>ivan.calderon@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/04/05/templating-with-handlebars.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/158</id>
    <published>2013-02-20T18:43:37Z</published>
    <updated>2013-03-19T17:22:13Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/aJ6bv5t8Poo/using-kaminari.html" />
    <title>Using Kaminari</title>
    <content type="html">&lt;p&gt;Hello there,&lt;/p&gt;

&lt;p&gt;Today I’d like to talk about pagination in Rails. When I started to learn RoR I did a simple application that included some products &amp;quot;to sell&amp;quot;, with description, stock, price, an image of the product, etc. You could add, delete, edit and all this kind of things that we always have in this type of applications.&lt;/p&gt;

&lt;p&gt;One of the problems that I found doing that was that if I added several different products I could get a very large list of items and see them in a scroll down list, but that was a bit tedious  &amp;gt;.&amp;lt;!&lt;/p&gt;

&lt;p&gt;After a while I was able to find a solution to the problem, and that’s what I want to show you now, how to use &lt;strong&gt;&amp;quot;kaminari&amp;quot;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Kaminari gives us an easy way of pagination; first you have to add it into the Gemfile.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;#39;kaminari&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then run &lt;strong&gt;bundle&lt;/strong&gt; to install it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kaminari uses a scope &lt;strong&gt;page&lt;/strong&gt; for an ActiveRecord model. For example, if you have 50 items and then write this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Product.page(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;… you are getting nothing. Using &lt;strong&gt;page&lt;/strong&gt; you can decide in what page you are going to be located in your application. Default per_page is 25 so, in this case we are trying to be in page 5, but since we only have 50 items we need to add 75 more because 125 items is the minimum amount for this. You can change this value using the &lt;strong&gt;per&lt;/strong&gt; scope. Look at this example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Product.page(4).per(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which means that if you have a list with 10 items you are going to have as a result 5 pages with 2 items per page, and you are going to be located in the 4th page, but you are not going to be able to navigate to other pages because we are selecting page 4 by default. You can see what I mean here:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/107/example.png" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;Fixing that, you have to modify your controller, in my case that is &amp;quot;products_controller.rb&amp;quot;. I used the index action and the &lt;strong&gt;:page&lt;/strong&gt; parameter to navigate in all the pages.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def index
   @products = Product.order(&amp;quot;description&amp;quot;).page(params[:page]).per(2)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We need to modify our template to use the helper method called &lt;strong&gt;paginate&lt;/strong&gt; and we have to transfer the list of products that we want to paginate. So, we have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;products/index.html.erb&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;H1&amp;gt;&amp;lt;% title &amp;quot;Products&amp;quot; %&amp;gt;&amp;lt;/H1&amp;gt;
&amp;lt;table&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;th&amp;gt;Image url&amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;
    &amp;lt;th&amp;gt;Buy&amp;lt;/th&amp;gt;
  &amp;lt;/tr&amp;gt;

&amp;lt;%= paginate @products %&amp;gt;
&amp;lt;div id=&amp;quot;products&amp;quot;&amp;gt;
    &amp;lt;%= render @products %&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;p&amp;gt;
  Item Count: &amp;lt;%= @order.order_items.count %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;Create a New Product&amp;quot;, new_product_path, :id =&amp;gt; &amp;quot;new_product&amp;quot; %&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;products/_product.html.erb&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;tr&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= image_tag &amp;quot;/images/products/#{product.image_url}&amp;quot; %&amp;gt;&amp;lt;td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= product.title %&amp;gt;&amp;lt;%= product.description %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= print_price(product.price) %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= raw(print_stock(product.stock)) %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= button_to &amp;quot;Add to Cart&amp;quot;, order_items_path(:product_id =&amp;gt; product.id) %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#39;Show&amp;#39;, product %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#39;Edit&amp;#39;, edit_product_path(product) %&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;%= link_to &amp;#39;Destroy&amp;#39;, product, :confirm =&amp;gt; &amp;#39;Are you sure?&amp;#39;, :method =&amp;gt; :delete %&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To navigate between the pages we have &amp;quot;Prev&amp;quot; and &amp;quot;Next&amp;quot; by default, as you can see in the first image. You can change these words adding the next code in &lt;strong&gt;config/locales/en.yml&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  hello: &amp;quot;Hello world&amp;quot;
  views:
    pagination:
      previous: &amp;quot;&amp;amp;lt; Previous Previous&amp;quot;
      next: &amp;quot;Next Next &amp;amp;gt;&amp;quot;
      truncate: &amp;quot;...&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you will see the changes:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/108/example2.png" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;strong&gt;kaminari&lt;/strong&gt; for any ActiveRecord queries and it&amp;#39;s very easy. You need to use the scope &lt;strong&gt;per&lt;/strong&gt; after &lt;strong&gt;page&lt;/strong&gt; and it will work like a charm.&lt;/p&gt;

&lt;p&gt;This is a simple example to understand how to use &lt;strong&gt;kaminari&lt;/strong&gt;. I hope it is useful to you.&lt;/p&gt;

&lt;p&gt;You can find more information &lt;a href="https://github.com/amatsuda/kaminari"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://railscasts.com/episodes/254-pagination-with-kaminari"&gt;http://railscasts.com/episodes/254-pagination-with-kaminari&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://asciicasts.com/episodes/254-pagination-with-kaminari"&gt;http://asciicasts.com/episodes/254-pagination-with-kaminari&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned, &lt;/p&gt;

&lt;p&gt;E. &lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/aJ6bv5t8Poo" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/2640b9e21e40d04c5f34e05950f00314.png?r=PG</photo>
    <author>
      <name>Erika Mejía</name>
      <email>erika.mejia@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/03/19/using-kaminari.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/157</id>
    <published>2013-02-16T19:31:15Z</published>
    <updated>2013-03-12T17:10:07Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/Qci6LEE1vL8/buildnotify-the-ccmenu-for-linux.html" />
    <title>BuildNotify, the CCMenu for Linux</title>
    <content type="html">&lt;p&gt;Sometimes you&amp;#39;re working in a team where everyone is modifying files, adding features or refactorizing, which makes it complicated to follow changes. That&amp;#39;s when the TDD comes to place, ensuring the changes only modify the behaviour you want to modify, and nothing else. But it can be hard to know for sure if those changes will affect  production environments due to the specific setup features that might exist in the developer&amp;#39;s machine. That&amp;#39;s when services like &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt; come in handy, to make sure that every build is successful on production.&lt;/p&gt;

&lt;p&gt;Mac users have a cool app called &lt;a href="http://ccmenu.sourceforge.net/"&gt;CCMenu&lt;/a&gt;, that lets you connect the build server to a tray system icon, where everytime someone sends a build you can easily tell if something went wrong. Linux users have a very nice clone called BuildNotify.&lt;/p&gt;

&lt;p&gt;BuildNotify, as described in their website, is a CCMenu equivalent for Linux. It resides in your system tray and notifies you of the build status for different projects on your continuous integration servers. BuildNotify is largely inspired on the awesome CCMenu available for Mac.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh3.googleusercontent.com/--vr4HmG_Ybg/USJuBaLXYnI/AAAAAAAACiE/X1_GSd8ROvk/s420/screenshot1.png" alt="BuildNotify"&gt;&lt;/p&gt;

&lt;h2&gt;Features&lt;/h2&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt; Monitor projects on multiple CruiseControl continuous integration servers.&lt;/li&gt;
&lt;li&gt; Access to overall continuous integration status from the system tray.&lt;/li&gt;
&lt;li&gt; Access individual project pages through the tray menu.&lt;/li&gt;
&lt;li&gt; Receive notifications for fixed/broken/still failing builds.&lt;/li&gt;
&lt;li&gt; Easy access to the last build time for each project&lt;/li&gt;
&lt;li&gt; Customize build notifications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Ubuntu installation (see special instructions for ver. 12.10 below)&lt;/h2&gt;

&lt;p&gt;The installation is pretty straightforward&lt;/p&gt;

&lt;p&gt;Run the following commands in a terminal&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo add-apt-repository ppa:anay/ppa
sudo apt-get update
sudo apt-get install python-buildnotify
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And done, you  have installed the CCMenu for Linux&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh3.googleusercontent.com/-A4ZHmnQbX-4/USJt-WpvAQI/AAAAAAAAChs/SQixIyK305A/s389/screenshot2.png" alt="BuildNotify installed"&gt;&lt;/p&gt;

&lt;h2&gt;Ubuntu 12.10 installation&lt;/h2&gt;

&lt;p&gt;Sadly, there is no repository for &lt;em&gt;Quantal&lt;/em&gt; yet. So don&amp;#39;t follow the previous steps because they will fail. To achieve this installation in &amp;quot;Quantal&amp;quot; follow the instructions for the fix. &lt;/p&gt;

&lt;p&gt;First add the repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo add-apt-repository ppa:anay/ppa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then go to Software Sources&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh3.googleusercontent.com/-oLwmwFr6IfI/USJt-Y4P49I/AAAAAAAAChw/J9bcoE_bGbk/s273/screenshot3.png" alt="Software Sources"&gt;&lt;/p&gt;

&lt;p&gt;Look for the &amp;quot;Other Software&amp;quot; tab and search for the two &amp;quot;anay&amp;quot; repositories and click on Edit.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh4.googleusercontent.com/-8s-PvoBozP0/USJxLomDLWI/AAAAAAAACiQ/bVDNUqpyYtM/s643/screenshot4.png" alt="Other Software repositories"&gt;&lt;/p&gt;

&lt;p&gt;Change the &lt;em&gt;Distribution&lt;/em&gt; from &amp;quot;quantal&amp;quot; to &amp;quot;precise&amp;quot;.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh5.googleusercontent.com/-zQ0jf_kXitY/USJxLnwIlMI/AAAAAAAACiM/Bctq6mqeiZA/s643/screenshot5.png" alt="Edit software repository"&gt;&lt;/p&gt;

&lt;p&gt;When you finish with &lt;em&gt;main&lt;/em&gt; and &lt;em&gt;Source Code&lt;/em&gt; try the next commands. Now the system will find the repository and finish the process successfully.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install python-buildnotify
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Extra Information&lt;/h2&gt;

&lt;p&gt;CCMenu is a great tool, and now thanks to &lt;a href="https://bitbucket.org/Anay"&gt;Anay&lt;/a&gt; we have it on Linux with BuildNotify. &lt;/p&gt;

&lt;p&gt;Remember to check if you have installed the dependencies: &lt;em&gt;pyqt4&lt;/em&gt;, &lt;em&gt;pytz&lt;/em&gt; and &lt;em&gt;python-dateutil&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is the official project on &lt;a href="https://bitbucket.org/Anay/buildnotify"&gt;bitbucket&lt;/a&gt;, and the PPA is currently available at &lt;a href="https:launchpad.net/anay/+archive/ppa"&gt;launchpad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope you enjoy working with this as much as I do. Remember you can contact me via &lt;a href="mailto:david.vega@crowdint.com"&gt;email&lt;/a&gt;, or follow me on &lt;a href="https://twitter.com/zetacu"&gt;twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/Qci6LEE1vL8" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/12bb6ed9fbbd247ced563e5e7ff9fddc.png?r=PG</photo>
    <author>
      <name>David Vega</name>
      <email>david.vega@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/03/12/buildnotify-the-ccmenu-for-linux.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/159</id>
    <published>2013-02-20T18:51:45Z</published>
    <updated>2013-03-07T19:24:46Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/FMOUdeZMcug/upgrading-a-rails-application-to-4-0.html" />
    <title>Upgrading a Rails application to 4.0</title>
    <content type="html">&lt;p&gt;Now that &lt;a href="http://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/"&gt;Ruby 2.0 has been released&lt;/a&gt; as well as the first Rails 4.0 beta its a good time to try and migrate your apps from Rails 3.2 to Rails 4.0 and get all the goodies. If you are coming from Rails 3.1, I strongly recommend that you first upgrade to Rails 3.2 before attempting the migration to 4.0.&lt;/p&gt;

&lt;p&gt;If you still want to use Rails 4.0 edge from the Github repo, a few weeks ago I wrote a blog post on &lt;a href="http://blog.crowdint.com/2012/11/27/living-on-the-edge-osx-ml-or-how-to-install-ruby-2-0pre-and-rails-4-0pre.html"&gt;how to install Rails 4 beta&lt;/a&gt; which can still help you.&lt;/p&gt;

&lt;p&gt;Your mileage will vary depending on the Gems that you application rely on. So far I have found that most of the gems that I use require a very small changes to have them work nicely with Rails 4.0, in most of the cases just modifying the gemspec file to require rails-4.0.0.beta has been enough.&lt;/p&gt;

&lt;p&gt;As usual having a test suite can give you some peace of mind, if you don&amp;#39;t have one, then, good luck!&lt;/p&gt;

&lt;h2&gt;Upgrading Gemfile&lt;/h2&gt;

&lt;p&gt;The first step to update your app is to modify your Gemfile to use the &amp;#39;4.0.0.beta1&amp;#39; version of Rails:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby &amp;#39;2.0.0&amp;#39;

gem &amp;#39;rails&amp;#39;, &amp;#39;4.0.0.beta1&amp;#39;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#39;sass-rails&amp;#39;,   &amp;#39;~&amp;gt; 4.0.0.beta1&amp;#39;
  gem &amp;#39;coffee-rails&amp;#39;, &amp;#39;~&amp;gt; 4.0.0.beta1&amp;#39;

  gem &amp;#39;uglifier&amp;#39;, &amp;#39;&amp;gt;= 1.0.3&amp;#39;
end

gem &amp;#39;activerecord-deprecated_finders&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One thing to notice, is that we are including a new gem &lt;em&gt;activerecord-deprecated_finders&lt;/em&gt;, which is here to keep compatibility if your application uses deprecated finders like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;User.find(:all, conditions: { email: &amp;#39;some@email.com&amp;#39; }, limit: 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Right now, it is not a requirement that you change your application to remove deprecated ActiveRecord finders, but, from now on you should only use the new ActiveRecord API.&lt;/p&gt;

&lt;p&gt;We should give it a try and update our Gemfile.lock with bundler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle update 
$ bundle --binstubs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we are lucky enough, all other gems which are being used by our application should just work with Rails 4.0, if not, we should look around failing gem&amp;#39;s repository, there is a good chance that there is a branch being worked for compatibility with Rails 4.0.&lt;/p&gt;

&lt;h2&gt;Application.rb&lt;/h2&gt;

&lt;p&gt;One of the biggest changes in Rails 4, is that application.rb is no longer holding general application configuration, we can leave it as it is right now or we can follow the Rails 4 pattern and extract all of our global application configuration into initializers.&lt;/p&gt;

&lt;p&gt;All new Rails 4 applications now have the following initializers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;backtrace_silencers.rb       mime_types.rb    session_store.rb
filter_parameter_logging.rb  inflections.rb   secret_token.rb   wrap_parameters.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This change made application.rb become almost empty. &lt;/p&gt;

&lt;p&gt;Another important change in Rails 4, is that we can have encrypted session cookies just by changing the &lt;em&gt;session_store&lt;/em&gt; configuration from &lt;em&gt;:cookie_store&lt;/em&gt; to &lt;em&gt;:encrypted&lt;em&gt;session&lt;/em&gt;store&lt;/em&gt;, but this will invalid all previously set cookies. There is a way to keep signed cookies as valid and have new session cookies being encrypted with the use of &lt;em&gt;:upgrade&lt;em&gt;signature&lt;/em&gt;to&lt;em&gt;encryption&lt;/em&gt;cookie_store&lt;/em&gt;, for more details on how to use it here is nice &lt;a href="http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies"&gt;post on the EnvyLabs blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, make sure that you remove the &lt;em&gt;whiny_nils&lt;/em&gt; configuration from &lt;em&gt;development.rb&lt;/em&gt; and &lt;em&gt;test.rb&lt;/em&gt;, since it has been deprecated and does nothing on Rails 4.&lt;/p&gt;

&lt;h2&gt;Eager loading&lt;/h2&gt;

&lt;p&gt;On Rails 4 there is a new setting for our application that tells Rails to eager load all of our application classes, instead of relying on Rails autoloading. Eager loading our classes gives us a chance to have our application running in Thread Safe mode, but this does not mean in any way that our application &lt;em&gt;is&lt;/em&gt; Thread Safe, this is true if any of our classes or a gem does changes to shared memory without a lock.&lt;/p&gt;

&lt;p&gt;By default, on a new Rails 4 application, a setting in our production.rb will tell Rails that we want to eager load and remove Rack::Lock middleware by default.&lt;/p&gt;

&lt;p&gt;Recomendations for this setting are as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# development
config.cache_classes = false
config.eager_load = false

# test
config.cache_classes = true
config.eager_load = false

# production
config.cache_classes = true
config.eager_load = true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="https://github.com/rails/rails/pull/7225"&gt;Commit comments&lt;/a&gt; for this feature gives more information about eager loading.&lt;/p&gt;

&lt;p&gt;I strongly suggest that you test your application as much as you can, just to be sure that there is no a side effect on enabling eager load on production. &lt;/p&gt;

&lt;h2&gt;Strong parameters&lt;/h2&gt;

&lt;p&gt;Rails 4 changes the way we pass form parameters to create or update a model within a controller. This is done with the introduction of Strong Parameters, which is a way to whitelist the parameters that can be passed to a model. It differs from protected attributes, this whitelist is defined on the controller and not the model, also it&amp;#39;s possible to define multiple whitelists for different use cases.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Methods defined in a controller
def create
  @user = User.new create_user_params
  …
end

def update
  @user = User.find params[:id]
  @user.update_attributes update_user_params
  …
end

def create_user_params
  params.require(:user).permit(:name, :age, :admin)
end

def update_user_params
  params.require(:user).permit(:name, :age)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a big change and a deal breaker for apps being migrated over Rails 4, since this will require a lot of effort on what was already working code.&lt;/p&gt;

&lt;p&gt;So, we have 2 options here:&lt;/p&gt;

&lt;p&gt;Use the &lt;em&gt;protected_attributes&lt;/em&gt; gem to keep compatibility and avoid big changes, in this case we need to create an initializer with a setting to use it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Rails.application.config.active_record.whitelist_attributes = true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second option is to bring the &lt;em&gt;strong_parameters&lt;/em&gt; gem to your application before upgrading to Rails 4, on every model were you want to migrate to strong parameters you must include the &lt;em&gt;ActiveModel::ForbiddenAttributesProtection&lt;/em&gt; module.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class User &amp;lt; ActiveRecord::Base
  include ActiveModel::ForbiddenAttributesProtection
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you are done migrating all your models, then you can remove the inclusion of that module on your models and add an initializer to have the module included into &lt;em&gt;ActiveRecord::Base&lt;/em&gt; class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally also disable the white list configuration in your &lt;em&gt;application.rb&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.active_record.whitelist_attributes = false
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Extraction and deprecation&lt;/h2&gt;

&lt;p&gt;Rails 4 was an opportunity for the core team to extract code that was deprecated, either because its not needed or because a better pattern came up or just to simplify Rails dependencies.&lt;/p&gt;

&lt;p&gt;So, if your application depends on Observers, Active Record Session Store, Action Caching, Page Caching then you should include in your migrated application the following gems, depending on your case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rails-observers, in this case you will need an initializer to specify the observers configuration ( see below this list )&lt;/li&gt;
&lt;li&gt;activerecord-session_store&lt;/li&gt;
&lt;li&gt;actionpack-action_caching&lt;/li&gt;
&lt;li&gt;actionpack-page_caching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure your observers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Rails.application.config.active_record.observers = :my_observer
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Final steps&lt;/h2&gt;

&lt;p&gt;At this point you should be able to test your application with your test suite and, just to be safe, with the help of a Q&amp;amp;A team. Hopefully there will not be any big issue that prevent you from moving to Rails 4.&lt;/p&gt;

&lt;p&gt;Even when Rails 4 is still a moving target, it could be a good time to evaluate what will be the effort of moving to this version of Rails.&lt;/p&gt;

&lt;p&gt;If you run in any kind of issues while testing your application, please report them to the Rails issue tracker, so they can be addressed before Rails 4 see the light.&lt;/p&gt;

&lt;p&gt;So far I only know of 2 applications that run Rails 4 in production, one of them is 37Signals&amp;#39; Basecamp Next and Github&amp;#39;s gists service.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/FMOUdeZMcug" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/86a035aafaaf39fe160a0644dc3be841.png?r=PG</photo>
    <author>
      <name>Mario Chavez</name>
      <email>mario.chavez@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/03/07/upgrading-a-rails-application-to-4-0.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/162</id>
    <published>2013-03-05T01:16:48Z</published>
    <updated>2013-03-05T16:17:06Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/nOcvBvayE5k/more-features-that-shipped-with-ruby-2-0.html" />
    <title>More features that shipped with Ruby 2.0</title>
    <content type="html">&lt;p&gt;I had the honor to attend &lt;a href="http://waza.heroku.com"&gt;Heroku Waza&lt;/a&gt; last week. The conference in general was amazing, however, there was a talk that (to me) was more interesting than any other.&lt;/p&gt;

&lt;p&gt;Ruby 2.0 was &lt;a href="http://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/"&gt;released last week&lt;/a&gt;, and at Waza, Matz tried to give us a glimpse of all the new features that shipped with it.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://ciblogassets.s3.amazonaws.com/crowdblog/asset/110/matz.JPG" alt="image alt"&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, time was not enough and Matz only had a chance to talk in detail about the features that &lt;a href="http://blog.crowdint.com/2012/11/05/3-killer-features-that-are-coming-on-ruby-2-0.html"&gt;Akira Matsuda already described&lt;/a&gt; at RubyConf last year.&lt;/p&gt;

&lt;p&gt;However, Matz did mention a few more, so, I decided to investigate a and write a little bit more about it, so, here they are.&lt;/p&gt;

&lt;h2&gt;Keyword arguments&lt;/h2&gt;

&lt;p&gt;If you come from a language like C#, this is very familiar, and its probably one of the things that you miss the most.&lt;/p&gt;

&lt;p&gt;To do something similar in 1.9.2, you have to pass an &lt;em&gt;options&lt;/em&gt; hash to the function where you want named parameters.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=arguments-1.rb"&gt;&lt;/script&gt;

&lt;p&gt;It works, however, things get ugly when you need defaults for those parameters.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=arguments-2.rb"&gt;&lt;/script&gt;

&lt;p&gt;It still works, but code begins to look complicated. You are doing things like merging a hash into another hash just to get the parameters of the options.&lt;/p&gt;

&lt;p&gt;Enter Named Arguments.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=arguments-3.rb"&gt;&lt;/script&gt;

&lt;p&gt;As you can see, you get the same functionality with less code.&lt;/p&gt;

&lt;p&gt;Also, you can combine them with regular parameters.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=arguments-4.rb"&gt;&lt;/script&gt;

&lt;p&gt;If you ask me, methods and their options are more descriptive this way. It will make Ruby code even more legible than it already is.&lt;/p&gt;

&lt;p&gt;I can see Rails taking advantage of this all over the place.&lt;/p&gt;

&lt;h2&gt;To_h&lt;/h2&gt;

&lt;p&gt;We can now convert objects to hashes using the, very simple, &lt;em&gt;.to_h&lt;/em&gt; that comes with some classes.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=to_h.rb"&gt;&lt;/script&gt;

&lt;p&gt;A simple example, I couldn&amp;#39;t think of a better one right now. However, I am sure that we will see plenty of this feature being used in the wild very soon.&lt;/p&gt;

&lt;h2&gt;Symbol array literals&lt;/h2&gt;

&lt;p&gt;This one blew my mind, I loved it.&lt;/p&gt;

&lt;script src="https://gist.github.com/dabit/5087199.js?file=array-literals.rb"&gt;&lt;/script&gt;

&lt;p&gt;The example speaks for itself, get a list of symbols from a list of words. Beautiful.&lt;/p&gt;

&lt;h2&gt;DTrace support&lt;/h2&gt;

&lt;p&gt;I have never actually used DTrace, but, I&amp;#39;ve heard of it.&lt;/p&gt;

&lt;p&gt;From it&amp;#39;s &lt;a href="http://en.wikipedia.org/wiki/DTrace"&gt;Wikipedia page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DTrace can be used to get a global overview of a running system, such as the amount of memory, CPU time, filesystem and network resources used by the active processes. It can also provide much more fine-grained information, such as a log of the arguments with which a specific function is being called, or a list of the processes accessing a specific file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds like a lot of debugging power. DTrace will become a powerful ally in the quest for memory leaks and any number of weird runtime errors.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Go upgrade your code to use Ruby 2.0 right now. It&amp;#39;s not 100% backwards compatible with 1.9.x, but, it&amp;#39;s pretty close.&lt;/p&gt;

&lt;p&gt;So far I haven&amp;#39;t found anything challenging when migrating apps from 1.9.&lt;/p&gt;

&lt;p&gt;Also, I didn&amp;#39;t mention performance. Ruby 2.0 + Rails 4 is faster. Noticeable faster. But, I&amp;#39;ll write more about that in another post.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/nOcvBvayE5k" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/72d86bb5aaaa1720ede338f4ad613344.png?r=PG</photo>
    <author>
      <name>David Padilla</name>
      <email>david.padilla@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/03/05/more-features-that-shipped-with-ruby-2-0.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/156</id>
    <published>2013-02-12T22:08:34Z</published>
    <updated>2013-03-05T06:54:44Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/ma8s0vIReTw/respect-the-tomato.html" />
    <title>Respect the tomato</title>
    <content type="html">&lt;p&gt;In the past few months, I&amp;#39;ve been using the &lt;a href='http://www.pomodorotechnique.com/'&gt;Pomodoro Technique®&lt;/a&gt; at work, specially when &lt;a href='http://en.wikipedia.org/wiki/Pair_programming'&gt;pair programming&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This technique is a really simple time-management tool created by Francesco Cirillo, and it takes its name from kitchen timers, those you can easily identify because they are shaped like tomatoes.&lt;/p&gt;

&lt;p&gt;In this post, I&amp;#39;d like to mention the advantages we get when applying the Pomodoro Technique® while working in pairs.&lt;/p&gt;

&lt;p&gt;First of all, I&amp;#39;d like to explain briefly how this technique works: the main idea is to focus your attention on a single task for 25-minute long spans, avoiding distractions in your work environment. You have to take a 5-minute break. &lt;/p&gt;

&lt;p&gt;During the break, you are allowed to do anything you want: check your email, make phone calls, attend to other people, get some coffee, etc. The point is to change the focus on anything but the task you are working for. The 25-minute session is known as a Pomodoro, the italian word for tomato. After the break, a new Pomodoro begins, in order to continue the task or start a new one.&lt;/p&gt;

&lt;p&gt;Once you complete four pomodori (plural for pomodoro), a longer break begins, that could last 20 or 25 minutes.  &lt;/p&gt;

&lt;p&gt;The main goal of this way of doing things is to focus fully on a single task, without forgetting that is important to take regular breaks. The outcome of using this method is a fresh and focused mind.&lt;/p&gt;

&lt;h2&gt;Pomodoro and pair programming&lt;/h2&gt;

&lt;p&gt;The Pomodoro Technique® works great with pair programming because distractions are minimized, specially when the rest of the team and coworkers know and understand this way of accomplishing goals.&lt;/p&gt;

&lt;p&gt;Another good thing is the possibility of switching drivers allowing programmers to take different roles in each pomodoro.&lt;/p&gt;

&lt;p&gt;Both users focus on finishing their tasks as soon as they can, because the countdown urges them to accomplish the activities planned for the sprint. &lt;/p&gt;

&lt;h2&gt;Advantages&lt;/h2&gt;

&lt;p&gt;These are the main advantages from my point of view:
&lt;ol&gt;
&lt;li&gt;Initial planning and decomposition of tasks into smaller entities.&lt;/li&gt;
&lt;li&gt;Less anxiety about getting the work done.&lt;/li&gt;
&lt;li&gt;Short iterations keep motivation.&lt;/li&gt;
&lt;li&gt;Less distractions help you to stay focused.&lt;/li&gt;
&lt;li&gt;You learn to prioritize your activities.&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;From my experience, using this technique has helped me to discipline my mind during working hours, forcing me to break activities down to smaller (easier to handle) tasks, focusing my attention and avoiding distractions, specially when pair programming, because we have to respect the time for work and the time for breaks of everyone involved in the activity. We have to respect the tomato.&lt;/p&gt;

&lt;p&gt;I quickly adapted to the technique, even more after noticing the benefits reflected in my productivity and concentration. Now I can hardly work without it.&lt;/p&gt;

&lt;p&gt;Distractions will never disappear completely, but they will be significantly minimized. And in case they keep stealing your time, this technique will help you get rid of them.&lt;/p&gt;

&lt;p&gt;It is worth trying this tool if you are looking for a way to stay focused, finish your work as planned, and maximize your time.&lt;/p&gt;

&lt;h2&gt;Resources and interesting reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.pomodorotechnique.com/'&gt;The Pomodoro Technique®&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://www.lifehack.org/articles/productivity/the-pomodoro-technique-is-it-right-for-you.html'&gt;The Pomodoro Technique: Is It Right For You?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://blog.staffannoteberg.com/2008/02/22/pomodoro-technique-in-5-minutes/'&gt;Pomodoro Technique® in 5 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://tomatoi.st/esop'&gt;Tomato.ist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/ma8s0vIReTw" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/5f57f95316c3ef6038e1da3fe7322b0c.png?r=PG</photo>
    <author>
      <name>Ana Castro</name>
      <email>ana.castro@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/03/04/respect-the-tomato.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/140</id>
    <published>2012-11-27T16:09:43Z</published>
    <updated>2013-02-27T19:03:46Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/qD_O8fSgUEQ/how-to-limit-two-decimal-digits-in-a-jquery-input-field.html" />
    <title>How to limit two decimal digits in a jQuery input field</title>
    <content type="html">&lt;p&gt;Hello there, this time I&amp;#39;d like to explain how to limit two decimal digits in a jQuery input field. This is how to do it:&lt;/p&gt;

&lt;h3&gt;HTML code&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;one&amp;quot; class=&amp;quot;two-digits&amp;quot;&amp;gt;&amp;lt;br&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;two&amp;quot; class=&amp;quot;two-digits&amp;quot;&amp;gt;​
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Javascript code&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt; // apply the two-digits behaviour to elements with &amp;#39;two-digits&amp;#39; as their class
 $( function() {
 $(&amp;#39;.two-digits&amp;#39;).keyup(function(){
   if($(this).val().indexOf(&amp;#39;.&amp;#39;)!=-1){         
       if($(this).val().split(&amp;quot;.&amp;quot;)[1].length &amp;gt; 2){                
           if( isNaN( parseFloat( this.value ) ) ) return;
           this.value = parseFloat(this.value).toFixed(2);
       }  
    }            
    return this; //for chaining
 });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;A tool for creating sample code&lt;/h4&gt;

&lt;p&gt;Here&amp;#39;s an useful tool to create sample code suitable for our needs.&lt;/p&gt;

&lt;p&gt;(&lt;a href="http://jsfiddle.net/c4Wqn/"&gt;http://jsfiddle.net/c4Wqn/&lt;/a&gt;) &lt;/p&gt;

&lt;h4&gt;In Haml and CoffeeScript&lt;/h4&gt;

&lt;h4&gt;Haml code&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt; %input#other_amount.numeric{type: &amp;#39;text&amp;#39;, name: &amp;#39;other_amount&amp;#39;}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Coffescript code:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;//Use this function to validate an input to limit with 2 decilmals after decimal point
$.fn.twoDigits = -&amp;gt;
   unless $(this).val().indexOf(&amp;quot;.&amp;quot;) is -1
   if $(this).val().split(&amp;quot;.&amp;quot;)[1].length &amp;gt; 2
     return if isNaN(parseFloat(this.val()))
     result = parseFloat(this.val()).toFixed(2)
     this.val result
     result
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;How to summon from our view&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt; $(&amp;#39;#other_amount&amp;#39;).twoDigits()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hope you found this guide useful. Shoot me up any comments you may have. Thank you for visiting our blog!&lt;/p&gt;

&lt;p&gt;H. &lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/qD_O8fSgUEQ" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/a4d868c8478241303110aa2eeddef2af.png?r=PG</photo>
    <author>
      <name>Heriberto Peréz</name>
      <email>heriberto.perez@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/02/27/how-to-limit-two-decimal-digits-in-a-jquery-input-field.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/155</id>
    <published>2013-02-11T18:38:47Z</published>
    <updated>2013-02-19T15:56:27Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/PqEaH5OUtT4/how-to-manage-file-uploads-with-backbone-js-paperclip-jquery-file-upload-and.html" />
    <title>How to manage file uploads with Backbone.js, paperclip, jquery file upload and...</title>
    <content type="html">&lt;p&gt;Hello there, &lt;/p&gt;

&lt;p&gt;A few days ago I was looking for a step-by-step tutorial on how to manage file uploads with the tools I mention in the title, and I couldn&amp;#39;t find one, so I decided to write one myself!&lt;/p&gt;

&lt;p&gt;In the first part of the tutorial, I show you a gallery made in Backbone plus Coffeescript, Haml, Eco templates, the jQuery file upload tool, Rails, Paperclip, and Amazon AWS. &lt;/p&gt;

&lt;p&gt;First of all, we need to create a new Rails project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rails new jqueryfileuploadbackbone
$ cd jqueryfileuploadbackbone
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Gemfile configuration should be the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; source &amp;#39;https://rubygems.org&amp;#39;
# Bundle edge Rails instead:     
# gem &amp;#39;rails&amp;#39;, :git =&amp;gt;; &amp;#39;git://github.com/rails/rails.git&amp;#39;

gem &amp;#39;haml&amp;#39;
gem &amp;#39;jquery-rails&amp;#39;
gem &amp;#39;rails&amp;#39;, &amp;#39;3.2.11&amp;#39;
gem &amp;#39;paperclip&amp;#39;, &amp;#39;~&amp;gt;; 3.4.0&amp;#39;
gem &amp;#39;aws-sdk&amp;#39;, &amp;#39;~&amp;gt;; 1.6.0&amp;#39;
gem &amp;#39;aws-s3&amp;#39;
#gem &amp;#39;mysql2&amp;#39;
gem &amp;#39;pg&amp;#39;
gem &amp;#39;devise&amp;#39;
gem &amp;#39;jquery-fileupload-rails&amp;#39;
gem &amp;#39;rb-readline&amp;#39;
gem &amp;#39;debugger&amp;#39;
# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#39;backbone-on-rails&amp;#39;
  gem &amp;#39;backbone-support&amp;#39;
  gem &amp;#39;coffee-rails&amp;#39;, &amp;#39;~&amp;gt;; 3.2.1&amp;#39;
  gem &amp;#39;eco&amp;#39;
  gem &amp;#39;haml_assets&amp;#39;
  gem &amp;#39;sass-rails&amp;#39;, &amp;#39;~&amp;gt;; 3.2.3&amp;#39;
  gem &amp;#39;sass&amp;#39;

   # See https://github.com/sstephenson/execjs#readme for more    supported runtimes
  # gem &amp;#39;therubyracer&amp;#39;, :platforms =&amp;gt;; :ruby

 gem &amp;#39;uglifier&amp;#39;, &amp;#39;&amp;gt;= 1.0.3&amp;#39;
end

group :test, :development do
  gem &amp;#39;fabrication&amp;#39;
  gem &amp;#39;guard-rspec&amp;#39;
  gem &amp;#39;rspec-rails&amp;#39;
end

#  To use ActiveModel has_secure_password
# gem &amp;#39;bcrypt-ruby&amp;#39;, &amp;#39;~&amp;gt;; 3.0.0&amp;#39;

# To use Jbuilder templates for JSON
# gem &amp;#39;jbuilder&amp;#39;

# Use unicorn as the app server
# gem &amp;#39;unicorn&amp;#39;

# Deploy with Capistrano
# gem &amp;#39;capistrano&amp;#39;

# To use debugger
# gem &amp;#39;debugger&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to install all the Gems using the next command&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  $ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to create a model to save our images and additional data, I&amp;#39;ll create one called &amp;#39;qrcodes&amp;#39;, where &amp;#39;image&amp;#39; will be where I save the image name, which is a requirement of the Paperclip Gem.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; $ rails generate model Qrcode description:string
 $ rake db:setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to prepare our model to upload images, for this effect just run the next command generator for Paperclip, this is where we specify our model and the attribute where we&amp;#39;ll save our images.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;   $ rails generate paperclip Qrcode image
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to run all of our migrations &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  $ rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now comes the moment to generate our Backbone structure (models, views, routes, etc), we can use Scaffold like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  $ rails g backbone:install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we continue with the creation of our controller and two methods to upload and show all of the images that were transferred.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  $ rails g controller qrcodes index create --skip javascript
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After using the previous command, we are going to create our routes to use it, for this we&amp;#39;re going to edit the file routes.rb located in&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; config/routes.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We are going to declare the next two lines if they don&amp;#39;t already exist&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get &amp;#39;qrcodes/index&amp;#39;
root to: &amp;#39;qrcodes#index&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to delete the public index file, to show the root page index in the qrcodes controller, used in the previous step.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public/index.html.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we have done everything correctly, we can now run our server using the rails server command so we can receive pop alerts in the address:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&amp;#39;s modify the following file to enable our routes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app/assets/javascripts/jqueryfileuploadbackbone.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adding the following code: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  window.Jqueryfileuploadbackbone =
      Models: {}
      Collections: {}
      Views: {}
      Routers: {}
      ManageImages: -&amp;gt;
      new Jqueryfileuploadbackbone.Routers.Qrcodes()
         alert &amp;#39;in backbone&amp;#39;
         Backbone.history.start()

   $(document).ready -&amp;gt;
      Jqueryfileuploadbackbone.ManageImages()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At this point we need to verify that all works fine. If we had any issues with Javascript we need to check the application.js file.  For example, I had to change the original content because I had  problems with the Backbone templates and I fixed it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;//= require jquery
//= require jquery_ujs
//= require_self
//= require underscore
//= require backbone
//= require jqueryfileuploadbackbone
//= require_tree ../templates/
//= require_tree .//models
//= require_tree .//collections
//= require_tree .//views
//= require_tree .//routers
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we&amp;#39;re going to edit our routers file to show our images list, the file is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  app/assets/javascripts/routers/qrcodes_router.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And add the following content:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class Jqueryfileuploadbackbone.Routers.Qrcodes extends Backbone.Router
    routes:
        &amp;#39;&amp;#39; : &amp;#39;showManageImages&amp;#39;
    showManageImages: -&amp;gt;
      @collection = new Jqueryfileuploadbackbone.Collections.Qrcodes()
      @collection.fetch()
      view = new Jqueryfileuploadbackbone.Views.QrcodesIndex collection: @collection
      $(&amp;#39;#container-app&amp;#39;).html view.render().el
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the previous code we can see that we need to use our collection to show all the images, but it is necesary to declare first the right routes in the config/routes.rb file like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; scope api do
  resources :qrcodes, format: false
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we are going to use our model to fetch all the data from the qrcode table, for that we use the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/assets/javascripts/models/qrcode.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we are going to specify the routes that we declared in the routes file, this is what I have:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class Jqueryfileuploadbackbone.Models.Qrcode extends Backbone.Model
   urlRoot: &amp;#39;api/qrcodes&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the same way, we are going to edit the collection file&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  app/assets/javacripts/collections/qrcodes.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Its content is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class Jqueryfileuploadbackbone.Collections.Qrcodes extends Backbone.Collection
   url: &amp;#39;api/qrcodes&amp;#39;
   model: Jqueryfileuploadbackbone.Models.Qrcode
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Important note: In this case I&amp;#39;m using Coffescript and it&amp;#39;s of great importance to be careful with the indentation spaces at all times.&lt;/p&gt;

&lt;p&gt;If you remember, in the Backbone router file we declared an div &amp;quot;container-app&amp;quot;, this will be used to attaching our Backbone app in ROR, the view in charge of doing that is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/views/qrcodes/index.html.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We are using haml (included in the Gemfile), and now we&amp;#39;re going to substitute the file extension .haml for .erb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app/views/qrcodes/index.html.haml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The contents of the file are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%h1 List of Images
#container-app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we are going to edit our qrcodes_index.js.coffee view&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/assets/javascripts/views/qrcodes_index.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As an example, we could use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Jqueryfileuploadbackbone.Views.QrcodesIndex extends Backbone.View
  template: JST[&amp;#39;qrcodes/index&amp;#39;]
  render:-&amp;gt;
   @$el.html @template
   @
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Continuing working with haml, we need to add the .haml extension to use it in our Eco template. The original file was:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/assets/templates/qrcodes/index.jst.eco
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it should look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/assets/templates/qrcodes/index.jst.eco.haml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we need to a link:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; =link_to &amp;#39;Add new Image&amp;#39;, &amp;#39;#qrcode/add&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now get to the interesting part, where we deal with file uploads. To do this we will create a new view:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/assets/javascripts/views/qrcodes/add_view.js.coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The content of the file to use the jQuery File Upload plugin in Backbone is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class Jqueryfileuploadbackbone.Views.QrcodesAddView extends Backbone.View
   template: JST[&amp;#39;qrcodes/add&amp;#39;]
   render: -&amp;gt;
    @$el.html @template
    @uploadQrcode()
   @

  uploadQrcode:=&amp;gt;
    @$el.fileupload
    add: (e, data)-&amp;gt;
       $(&amp;#39;#qrcode_image&amp;#39;).hide()
       $(&amp;quot;#fileupload-loading&amp;quot;).html &amp;#39;Cargando...&amp;#39;
       data.submit()


    formData: [
      name: &amp;#39;authenticity_token&amp;#39;
     value: $(&amp;quot;meta[name=\&amp;#39;csrf-token\&amp;#39;]&amp;quot;).attr(&amp;#39;content&amp;#39;)
   ]

   done: (e, data) -&amp;gt;
     window.location = &amp;#39;/&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And add template with the following content:&lt;/p&gt;

&lt;p&gt;The template file name is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app/assets/templates/qrcodes/add.jst.eco.haml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The content of the form to upload images is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;= form_tag &amp;#39;api/qrcodes&amp;#39;, :multipart =&amp;gt; true, :id =&amp;gt; &amp;#39;fileupload&amp;#39; do
  .fields
    = file_field(:qrcode, :image)
    #fileupload-loading{style: &amp;#39;height: 50px; width: 200px;&amp;#39;}
    %br
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&amp;#39;s add our route in qrcodes_router.js.coffee to use our new view to add images&lt;/p&gt;

&lt;p&gt;The updated content should be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Jqueryfileuploadbackbone.Routers.Qrcodes extends Backbone.Router
   routes:
     &amp;#39;&amp;#39; : &amp;#39;showManageImages&amp;#39;
     &amp;#39;qrcode/add&amp;#39; : &amp;#39;addNewImage&amp;#39;
   showManageImages: -&amp;gt; 
      @collection = new Jqueryfileuploadbackbone.Collections.Qrcodes()
      @collection.fetch() view = new Jqueryfileuploadbackbone.Views.QrcodesIndex collection: @collection
      $(&amp;#39;#container-app&amp;#39;).html view.render().el

   addNewImage : -&amp;gt;
     view = new Jqueryfileuploadbackbone.Views.QrcodesAddView
     $(&amp;#39;#container-app&amp;#39;).html view.render().el
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to declare our file upload plugin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;   app/assets/javascripts/application.js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we need to add the jquery file upload Gem (included in the Gemfile)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  //=require jquery-fileupload/basic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This the moment to configure the Paperclip gem to manage uploads in our server, first edit the file&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; app/models/qrcode.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The last content you need to add is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Qrcode &amp;lt; ActiveRecord::Base
 attr_accessible :description, :image
 has_attached_file :image,
    :url =&amp;gt; &amp;#39;/system/qrcodes/:filename&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;end&lt;/p&gt;

&lt;p&gt;Afterwards, we edit the qrcodes_controller.rb file with the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class QrcodesController &amp;lt; ApplicationController
   respond_to :json

   def index
  end

  def create
    respond_with Qrcode.create(params[:qrcode])
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additionally, run all the migrations:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  $ rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now we can run our server&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; $ rails server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#39;s test what we did. First, click in the add new image link. Then, browse for an image with the right format in the form. If the file uploads, we have a working application!&lt;/p&gt;

&lt;p&gt;Locally, the file should be located in the public/qrcodes directory. &lt;/p&gt;

&lt;p&gt;In another tutorial I will teach you how to list and delete images.&lt;/p&gt;

&lt;p&gt;Hope you found this tutorial useful. You can find the repo in github at:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; https://github.com/heridev/jqueryfileuploadbackbone
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See you next time!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/PqEaH5OUtT4" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/a4d868c8478241303110aa2eeddef2af.png?r=PG</photo>
    <author>
      <name>Heriberto Peréz</name>
      <email>heriberto.perez@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/02/19/how-to-manage-file-uploads-with-backbone-js-paperclip-jquery-file-upload-and.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/149</id>
    <published>2013-01-15T19:31:36Z</published>
    <updated>2013-01-29T16:32:49Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/a71CBhWNqc0/how-to-get-what-you-need-with-nokogiri.html" />
    <title>How to get what you need with Nokogiri</title>
    <content type="html">&lt;p&gt;Recently, I was asked to automate the retrieval of information from a  website that is not online anymore? Maybe you are thinking that finding such a site was the difficult part, but actually, it was the easy one.&lt;/p&gt;

&lt;p&gt;So, how to come up with an older, no-longer-running, version of a website? Well, that&amp;#39;s easy, you only need to pay a visit to the Internet Archive Wayback Machine at &lt;a href="http://web.archive.org/"&gt;http://web.archive.org/&lt;/a&gt; and find the website you are looking for in the database.&lt;/p&gt;

&lt;p&gt;Now, getting to the interesting part: automating the data collection. To achieve this goal we can use several techniques and technologies. In this post I&amp;#39;m going to explain the technique known as Screen Scraping. In a nutshell, with this technique you extract data from sources that are not typically designed for this purpose. Namely, an HTML document.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s picture an scenario. You want to get certain data from a website, but the site doesn&amp;#39;t have any web services to accomplish this purpose. Screen Scraping is useful for situations exactly like this. &lt;/p&gt;

&lt;p&gt;In my case, I had to collect data from a copy of a website stored on the Internet Archive Wayback Machine database, this means there was only HTML documents as sources of data. There weren&amp;#39;t any web services or other sources of data available. Specifically, I needed to generate an XML file with the data from all the Magma Rails 2012 speakers (&lt;a href="http://web.archive.org/web/20120608203123/http://www.magmarails.com/"&gt;http://web.archive.org/web/20120608203123/http://www.magmarails.com/&lt;/a&gt;). So, HTML is designed to present data, the question is: can I use the HTML source to automatically generate another piece of data? With Nokogiri (&lt;a href="http://nokogiri.org/"&gt;http://nokogiri.org/&lt;/a&gt;), we can use any website, look for the specific information we need, process the data and make any use we want of it. &lt;/p&gt;

&lt;p&gt;Let&amp;#39;s start with the Screen Scraping using Nokogiri. To begin, we need to install nokogiri&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install nokogiri
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next step is to identify the HTML elements we need to access and get its information. Nokogiri allows us to match the HTML elements using the CSS selectors. I have described to you the problem and the source of data. The CSS selector that matches all the speakers from the HTML document is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.speaker-item
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You can use Selector Gadget (&lt;a href="http://www.selectorgadget.com/"&gt;http://www.selectorgadget.com/&lt;/a&gt;) to make the identification of the needed elements easier. Selector Gadget is a very nice open-source bookmarklet.&lt;/p&gt;

&lt;p&gt;Following with the example, now we have to create our Ruby script file. At the top of the file we need to require two gems:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;nokogiri&amp;#39;
require &amp;#39;open-uri&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously, Nokogiri must be included. Now we have to get the HTML from the website and assign it to an object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;html = open(&amp;quot;http://web.archive.org/web/20120502173130/http://magmarails.com/&amp;quot;)
document = Nokogiri::HTML(html.read)
document.encoding = &amp;#39;utf-8&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, first, we opened the HTML document, after we created a Nokogiri HTML document with that, and finally we encoded the document to UTF-8. There is another way to do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;document = Nokogiri::HTML(open(&amp;quot;http://web.archive.org/web/20120502173130/http://magmarails.com/&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But, if the website has utf-8 encoding and you need to get the accented characters, you should send the HTML to Nokogiri as a raw string, because there is an issue between nokogiri and open-uri and you might have trouble if you don&amp;#39;t do this. &lt;/p&gt;

&lt;p&gt;The next step is to generate the XML file. But, before doing that I would like to explain you how Nokogiri access the elements of the HTML document. As I already mentioned, we can access the elements using CSS selectors, this is the main reason why I feel very comfortable with Nokogiri. How can we select the elements? Easy, Nokogiri brings us two methods to do this.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;css(selector)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;at_css(selector)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where &amp;#39;selector&amp;#39; is a string with any CSS selector, for instance:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#39;.container ul li&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The difference between &lt;em&gt;css&lt;/em&gt; and &lt;em&gt;at_css&lt;/em&gt; is that the first one returns a collection of all the coincidences for the selector, while  &lt;em&gt;at_css&lt;/em&gt; returns only the first instance.&lt;/p&gt;

&lt;p&gt;Okay, we just need to get the data from all the &amp;#39;.speaker-item&amp;#39; elements from the website. The following does the work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;speakers = document.css(&amp;#39;.speaker-item&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What that line of code does is to store all the elements with the class .speaker-item on my &lt;em&gt;speakers&lt;/em&gt; variable.&lt;/p&gt;

&lt;p&gt;Now we must declare a variable for auto-incrementing the &lt;strong&gt;speaker&amp;#39;s id&lt;/strong&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;speaker_id = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The final step is to create the XML file and put data on it, we now can access all of the speaker&amp;#39;s elements and get the data. We can get the data from a selected element with Nokogiri using the &lt;em&gt;text&lt;/em&gt; property. For instance:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;puts document.at_css(&amp;#39;h1&amp;#39;).text
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following code creates the XML file, and writes on it the entire structure with the information obtained from our &lt;em&gt;speakers&lt;/em&gt; collection. Now, we need to use an iteration to access each .speaker-item element on the collection and get the data.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;File.open(&amp;#39;speakers.xml&amp;#39;, &amp;#39;w+&amp;#39;) do |f|
  # For each speaker on speakers list do
  speakers.each do |speaker|
    f.puts(&amp;quot;&amp;lt;dict&amp;gt;\n&amp;quot;)
    f.puts(&amp;quot;\t&amp;lt;key&amp;gt;name&amp;lt;/key&amp;gt;\n&amp;quot;)
    # The speaker name is at the h1 element
    f.puts(&amp;quot;\t&amp;lt;string&amp;gt;#{speaker.at_css(&amp;#39;h1&amp;#39;).text}&amp;lt;/string&amp;gt;\n&amp;quot;)
    f.puts(&amp;quot;\t&amp;lt;key&amp;gt;speakerId&amp;lt;/key&amp;gt;\n&amp;quot;)
    # The speaker_id is generated automatically with the iteration
    f.puts(&amp;quot;\t&amp;lt;integer&amp;gt;#{speaker_id}&amp;lt;/integer&amp;gt;\n&amp;quot;)
    f.puts(&amp;quot;\t&amp;lt;key&amp;gt;twitter&amp;lt;/key&amp;gt;\n&amp;quot;)
    # The user&amp;#39;s twitter is at &amp;#39;.data p&amp;#39; element
    f.puts(&amp;quot;\t&amp;lt;string&amp;gt;#{speaker.at_css(&amp;#39;.data p&amp;#39;).text}&amp;lt;/string&amp;gt;\n&amp;quot;)
    f.puts(&amp;quot;\t&amp;lt;key&amp;gt;bio&amp;lt;/key&amp;gt;\n&amp;quot;)
    # The user&amp;#39;s bio is at &amp;#39;.bio p&amp;#39; element
    f.puts(&amp;quot;\t&amp;lt;string&amp;gt;#{speaker.at_css(&amp;#39;.bio p&amp;#39;).text}&amp;lt;/string&amp;gt;\n&amp;quot;)
    f.puts(&amp;quot;&amp;lt;/dict&amp;gt;&amp;quot;)
    speaker_id += 1
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;#39;s it. The product of our code is an XML file with 216 automatically generated lines. This is a very basic example, but the potential of Nokogiri is only limited by our creativity. &lt;/p&gt;

&lt;p&gt;As I already told you, this is only a small example. To give a larger example to better appreciate the potential of Nokogiri and the Screen Scraping technique, imagine you want to retrieve data from a website that includes a large quantity of data shown on an HTML table. With Nokogiri, you can access all of the rows in that table, and instantiate objects to do something with them or to store those rows in a database accessible from our application. If there were 10 to 20 rows of data you would probably do it manually, but if you had over a 1,000 rows you would need the help of Nokogiri.&lt;/p&gt;

&lt;p&gt;To conclude, Screen Scraping with Nokogiri is a great tool when we need to automatically extract data from a website, we don&amp;#39;t have any web services available, and our sources are HTML documents exclusively. &lt;/p&gt;

&lt;p&gt;Hope you enjoyed this short tutorial. &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Nokogiri can parse XML, SAX and Reader documents too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://railscasts.com/episodes/190-screen-scraping-with-nokogiri"&gt;http://railscasts.com/episodes/190-screen-scraping-with-nokogiri&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/2572396/nokogiri-open-uri-and-unicode-characters"&gt;http://stackoverflow.com/questions/2572396/nokogiri-open-uri-and-unicode-characters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/a71CBhWNqc0" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/fc195d4264f4805892342b49d5777a77.png?r=PG</photo>
    <author>
      <name>Eduardo Figarola</name>
      <email>eduardo.figarola@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/01/29/how-to-get-what-you-need-with-nokogiri.html</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.crowdint.com,2005:Post/148</id>
    <published>2013-01-15T03:15:29Z</published>
    <updated>2013-01-22T18:45:12Z</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CrowdInteractiveTechBlog/~3/Tqw6JSmABC0/coding-hardware-with-ruby-phidgets.html" />
    <title>Coding hardware with Ruby + Phidgets</title>
    <content type="html">&lt;p&gt;Ever wondered if you can take Ruby to the next level? Maybe program some hardware with it? Well, me too! And Phidgets is a great tool for accomplishing this goal. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.phidgets.com/"&gt;Phidgets&lt;/a&gt; (Physical Widgets), as the website stands are &amp;#39;... a set of &amp;quot;plug and play&amp;quot; building blocks for low cost USB sensing and control from your PC.&amp;#39; This means that we have a wide variety of sensors and controllers for us to choose to play with. Phidgets works with C/C++, C#, Cocoa, Delphi, Flash AS3, Flex AS3, Java, LabVIEW, MATLAB, Max/MSP, MRS, Python, REALBasic, Visual Basic.NET, Visual Basic 6.0, Visual Basic for Applications, Visual Basic Script, and Visual C/C++/Borland.NET... and now &lt;strong&gt;Ruby&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;In order to start working with Phidgets + Ruby + OSX there&amp;#39;s this really good &lt;a href="http://www.phidgets.com/docs/Language_-_Ruby"&gt;wiki&lt;/a&gt;, but if you want to start right away then I suggest to begin by installing the OSX driver and the &lt;a href="https://github.com/kreynolds/phidgets-ffi"&gt;phidgets-ffi&lt;/a&gt; ruby gem.&lt;/p&gt;

&lt;p&gt;After doing that, we can go to &amp;#39;System Preferences&amp;#39; and under the &amp;#39;Other&amp;#39; group we will find the Phidgets pane.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://cl.ly/image/0H3V0n390l2J/Screen%20Shot%202013-01-14%20at%207.44.02%20PM.png" alt="system preferences" title="system preferences"&gt; &lt;/p&gt;

&lt;p&gt;Enter the Phidgets pane and see the Phidgets devices connected to the computer. In my case I have a RFID reader and the Phidget InterfaceKit 8/8/8, with 8 digital inputs, 8 digital outputs and 8 analog inputs with configurable data acquisition rates on the board.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://cl.ly/image/2H150N272s0S/Screen%20Shot%202013-01-14%20at%207.49.43%20PM.png" alt="phidgets pane" title="phidgets pane"&gt;&lt;/p&gt;

&lt;p&gt;One of the coolest thigs about this pane is that if you double click on the interface kit you get a window where you can test it, see its information and read its inputs, here in the image you can see that I have two analogue sensors, a rotation sensor and a slider sensor (both potentiometers) inputs 0 and 5.
 If you move those sensors you can see the numbers change in real time.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://cl.ly/image/122O0K1C421h/Screen%20Shot%202013-01-14%20at%207.56.45%20PM.png" alt="interfacekit pane" title="interfacekit pane"&gt;&lt;/p&gt;

&lt;p&gt;Now that we can confirm that everything is working as it should, let&amp;#39;s get down to writing some code. &lt;/p&gt;

&lt;p&gt;I&amp;#39;m going to show you how to code a small example of the PhidgetRFID reader. The first thing that you need to do is install the Phidgets gem.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install phidgets-ffi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As the documentation of the gem states, phidgets-ffi is dependent on the ffi(&amp;gt;=1.0.9) gem. So, if the above command doesn&amp;#39;t automatically install the gem for you, then enter:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install ffi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The example code is too small so I&amp;#39;m going to paste it in full and then explain:&lt;/p&gt;

&lt;p&gt;&lt;script src="https://gist.github.com/4535499.js"&gt;&lt;/script&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line 2&lt;/strong&gt; will include the libraries included in the Phidgets gem, &lt;strong&gt;Line 6&lt;/strong&gt; is interesting because we are creating a Phidgets RFID object which we can configure in &lt;strong&gt;Lines 12&lt;/strong&gt; and &lt;strong&gt;13&lt;/strong&gt; in the on_attach hook from the RFID object we just created.
 &lt;strong&gt;Line 12&lt;/strong&gt; is critical because we&amp;#39;re activating the antenna and without it we wouldn&amp;#39;t be able to read tags, &lt;strong&gt;Line 13&lt;/strong&gt; is simply to turn on the LED in the reader.
 We need to have the sleep call in that configuration in order to give time for the reader to connect.&lt;/p&gt;

&lt;p&gt;Events on &lt;strong&gt;Line 17&lt;/strong&gt; and &lt;strong&gt;Line 21&lt;/strong&gt;, &amp;#39;on_tag&amp;#39; and &amp;#39;on_tag_lost&amp;#39; get called when we add or remove a RFID tag in the reader. And that&amp;#39;s pretty much it!&lt;/p&gt;

&lt;p&gt;Much of the coding for Phidgets follows the line of configuring the board and hooking up to events. Those events are called when the sensors activate by either a change of the brightness of the light, temperature variations, the flip of a switch, touching something, etcetera.  And it&amp;#39;s then when we can do stuff with our code, either logging those events or taking action using actuators, including servos, DC and stepper motors.&lt;/p&gt;

&lt;p&gt;If you want to know more, you can find more examples of how to program Phidgets with Ruby by looking at the Phidget&amp;#39;s gem source code, have fun!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/CrowdInteractiveTechBlog/~4/Tqw6JSmABC0" height="1" width="1"/&gt;</content>
    <photo>https://secure.gravatar.com/avatar/d2d66b4e429c04b16e74d65f44c92815.png?r=PG</photo>
    <author>
      <name>Fernando Castellanos</name>
      <email>fernando.castellanos@crowdint.com</email>
    </author>
  <feedburner:origLink>http://blog.crowdint.com/2013/01/22/coding-hardware-with-ruby-phidgets.html</feedburner:origLink></entry>
</feed>
