Posted by & filed under Javascript, Rails.

The Request and Requirements

A few days ago, a friend of mine asked me to create a simple CRUDing app. He had two requirements: it had to work completely off-line and be compatible with an Android tablet. Now this posed a few problems, the main one being: I am not an Android developer.

As I think more about this request, I know I can make the app entirely using javascript and then PhoneGap to make it compatible with Android. However, there is one big problem when starting a javascript app from scratch: organization. As I continue thinking about this app, I list a few other thoughts, requirements, questions, and desires of my own:

  1. Structure benefits javascript code and Backbone.js could provide this.
  2. I have had enough of those darn curly braces – I could write this in CoffeeScript.
  3. All the data has to be stored on the client’s side – I think localStorage would work.
  4. Compiling all assets into one css and js file would be awesome.
  5. A nice touch of Bootstrap would make it look professional.
  6. Is there anyway I could use bourbon or sass to make my life easier?
  7. Testing is always important especially if the feature requests grow.

All these thoughts make me realize I have one robust solution: Rails!

Rails? Really? You may ask. Why? Isn’t that a large solution for such a small app? Especially, for a client-side application?! You may be right, but please, let’s give Rails a second look.

The Gems

Over that past few years, the rails community has embraced js frameworks such as Backbone.js, AngularJS, and Ember.js. The rails asset pipeline makes integrating these frameworks quite easy. With the backbone-on-rails gem, js code can be organized nicely into Collections, Models, Views, and Route directories. With a localStorage adapter for Backbone.js, Backbone.localStorage, Rails no longer needs a server. I can write in coffeescript with the coffee-rails gem – included by default when you build a new Rails app. I am able to write clean js code for free.

As for css, things couldn’t be any simpler. I am tired of writing in css without sass, and by including sass-rails as a default, rails programmers can say ‘goodbye’ to redundant css. While I am at it, I decide to take advantage of Bootstrap 3. I mean, this app needs to be on a tablet right? And it can look professional too. I include anjlab-bootstrap-rails in my gem file, and one rake command later – rake assets:precompile – I get two precompiled files: application.css and application.js.

Testing

I am not sure how apps can exists anymore without testing, but don’t ask the government. No matter how small, I always seem to avoid problems or find ones problems with my code when testing. Rails testing frameworks are robust but simple to set up. I decide that if I am going to test the javascript, I need to automate the browser.

In other projects I have found Selenium to be a great solution. With the rspec-rails, capybara, database_cleaner, launchy, selenium-webdriver, and shoulda-matchers gems, I get it all. I get matchers, a FireFox test driver, and even a way to inspect a page with one of my favorite gems: launchy. Below is an example test:

require 'spec_helper'

describe "CRUD ToDos", :js => true do

  describe 'Index' do

    it 'user can view a table of all todos' do
      visit '/'
      should_see_in "h1", "ToDos"
      with_scope ".btn-toolbar" do
        page.should have_link "New ToDo", :href => "#todos/new"
      end
      with_scope "table#todos" do
        should_see "Title"
      end
    end

  end

end

I also want faster test execution and to reduce the boot up time of my server, console or any other execution so I include the zeus or spork gems. It is a major time saver.

Minor Changes to Rails

Once I have my rails-backbone app up and running, I need to make a few adjustments in order to have my code work with PhoneGap.

Updating your application.html.erb file

This is what a Rails application.html file looks like upon creation:

application.html.erb file created by default

I remove the ruby code and made sure my link and script tags point to the correct place:

augmented application.html file for PhoneGap

I add a div with an id ‘main’ and use this for all the backbone pages.

Creating a Rake Task for PhoneGap

My last step is to create a rake task that creates all the files necessary for PhoneGap. Viola, I have phonegap.zip file for easy code uploading.

require 'fileutils'
require 'zip/zip'

namespace :phonegap do

  task :build => [:environment, "assets:precompile"] do

    remove_dir("phonegap", true) if File.directory?('phonegap')

    mkdir("phonegap")
    cp("./app/views/layouts/application.html.erb", 'phonegap')
    File.rename('phonegap/application.html.erb', 'phonegap/index.html' )

    mkdir("phonegap/assets")
    cp("./public/assets/application.js", "phonegap/assets")
    cp("./public/assets/application.css", "phonegap/assets")

    mkdir("phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.eot", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.svg", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.ttf", "phonegap/assets/twitter")
    cp("./public/assets/twitter/glyphicons-halflings-regular.woff", "phonegap/assets/twitter")

    remove_file "phonegap.zip" if File.exist?("phonegap.zip")
    Dir["phonegap"].each do |file|
      if File.directory?(file)
        `zip -r "#{file}.zip" "#{file}"`
      end
    end

    Rake::Task["assets:clean"].execute

  end

end

Thank you so much for your time. Comments are appreciated.

  • Estanislao Vizcarra

    Interesting post, thanks por shared it. Right now im starting to see it how phonegap works and how use the database from a rails app, to create a phonegap app. If you have more info or other resources, are welcome. Thank you!

    • Andrei Miulescu

      hey Estanio I think the idea is to build something like an ember application and use that

  • sueboy

    Thank you very much! share this information.
    Let me know….rails can do this! Because now I try to understand Cordova.

    Now maybe I need to deep know rails.

  • yoel

    Hi , I’m trying to figure out how hard it will be to port my Rails website to a phonegap App .
    Are javascript frameworks like BackboneAngular a must ? Because that means I won’t be able to use my current views + make an API + write a bunch of javascript . Is there any straightforward way to just kinda wrap my website in a webview + some minor csshtml modifications for the mobile app , or do people usually go the Rails API route + javascript MVC framework?

  • Kiran

    is that code in github ? If not please upload it.