Tiny jQuery Mobile App Powered by Sinatra
In my article Ruboto: Ruby’s and Android’s First Born, I covered one way to use Ruby for mobile app development. In that article, we created a native Android app in JRuby that could run on Android’s Java Virtual Machine.
This time, we will dip our toes into the world of mobile web apps. These little buzzword magnets are basically regular web apps that have been highly optimized and all pimped up for mobile devices. Usually, the look and feel tries to resemble a native mobile app and, thanks to some newer HTML5 APIs, even access the devices sensors for some additional cool features.
What Are We Building?
I’m guessing everyone is expecting yet another todo app at this point. However, I can confidently say that, not only is this not the case but, we are actually building something that is based on a real life request by a friend of mine. She was testing some food supplements and wanted to track the effects. So, instead of letting her use pen and paper like a caveman, I suggested to build a mobile web app instead. That way she could pleasantly use it from her smartphone or any browser and later maybe even do some automated data analysis.
How Are We Going to Do It?
Craving quick results, I decided to select the technology stack accordingly:
In my opinion, these Gems provide a perfect playground for mobile app prototypes. Of course, if we were aiming for a bigger app with more than a handful of simple models and thousands of users, you’d definitely do things differently. But for a first prototype to get things rolling and impress clients or for private projects, you’ll have a hard time finding a much better stack.
Also, just to keep things simple (always a big plus on my list), I’ll show you how to do it all in a single file in under one hundred lines of code.
Let’s Get to Work!
Excited? Great! So, without further introduction, let’s start our project with a proper shebang line and require the needed Gems:
After this, it’s time to define the model classes. In our case, we actually only need one model to represent the events we are going to track:
A model usually needs some kind of persistence so we can restart the app and maintain our data. We will use a SQLite database for this and the DataMapper Gem as an ORM mainly for two reasons: On the one hand using an ORM like DataMapper allows us to change the database backend later on without changing our application logic and on the other hand DataMapper supports auto migrations- and schema creation. These are extremely sexy features, especially when you want to do really quick and agile prototype development. So, adding persistence to our app boils down to these two lines of code:
Eleven lines of code into the project, models and persistence done. It’s time to add some controllers or, in Sinatra terms, routes. Of course, we want to see a list of all the events that we added so far. This list of events will be our main page, for now. Besides that, we need to be able to add new events and save them. That makes three pretty simple and self explanatory routes:
Another nineteen lines makes thirty, and we are only missing some views now. Lucky for us, Haml is a pretty condensed way of writing HTML templates and Sinatra has an ace up its sleeve when it comes to tiny projects and views. We only need to end our Ruby file with the
__END__ statement to stop the interpreter from going any further, and then add our views like this:
A layout and two views in about fifty lines, not too bad. As you can see, we are loading jQuery, jQuery Mobile and an extra jQuery Mobile Datebox plugin directly from their remote sources. Note: The protocol part in a URL is optional, and omitting it will work for either HTTP and HTTPS without any changes.
If you eagerly copy/pasted all these snippets and want to run them now, you can do that with a simple
ruby pilltracker.rb or, when you remembered to set the executable bit of the file, even with
./pilltracker.rb hence the shebang. The app will work totally fine, assuming you have installed all needed Gems. It will also automatically create a database file in the working directory, but will be missing some images.
For a complete version of the code and images just clone this repository.
I hope you enjoyed this little project and maybe you even want to add a delete feature for further learning. As always, I’ll try to answer any questions and won’t be mad at all if you feel the urge to tweet about this article :)