Getting Started with jQuery Mobile & Rails 3
The very promising jQuery Mobile project is now in its first Alpha release! What better time to give it a spin with our (err… my) favorite web framework?!
You should read jQuery Mobile’s official introduction section to familiarize yourself with its principles, but in a few words: you include it on the page, format your markup to conform to its requirements and reap the benefits. Yay, let’s write a (very contrived) CRUD application with Rails 3 and jQuery Mobile!
Setup
Our application will allow us to create, read, update and delete blog posts (remember when I said it was contrived? Uhm..yah) from mobile devices. If you don’t have Rails 3 installed yet, you can get it via RubyGems:
gem install rails
Use the rails command line tool to generate a new application. We’ll call it jqmoblog.
rails new jqmoblog # ... a bunch of files are created cd jqmoblog
As of Rails 3.0.1 you cannot specify jQuery as the JavaScript tool of choice when you generate a Rails application, but we can easily swap it in by using the handy, dandy jquery-rails gem. Edit the Gemfile in the project’s root directory and add a dependency on the gem. Once finished your Gemfile will look something like this:
source 'http://rubygems.org' gem 'rails', '3.0.1' gem 'sqlite3-ruby', :require => 'sqlite3' gem 'jquery-rails'
Install the required gems using the bundle command line tool:
bundle install
Now we’ll use the Rails generator added by the jquery-rails gem to get all the jQuery files we need:
rails generate jquery:install
When prompted, allow it to overwrite rails.js.
We’re almost ready. The application skeleton is in place and jQuery has replaced the Rails default JavaScript libraries, but we’re missing the basic model, controller, and views for our application.
Thankfully, Rails has a generator which will create these files for us and its called the scaffold generator. We’ll keep the blog posts in our app super-simple since we’re really just using them to learn about jQuery Mobile. Each post will have a title and a body. Generate the scaffold for a Post resource like this:
rails generate scaffold Post title:string body:text
This command will provide a list of files and directories it created. There should be a model (app/models/post.rb), a controller (app/controller/posts_controller.rb), and a directory of views (app/views/posts) for our Post resource.
Run the database migration that was created from the scaffold command so our database has a posts table with the required columns for storing our posts:
rake db:migrate
At this point you can fire up a Rails server and the app will load up in your browser:
rails server
Point your browser to http://localhost:3000 and you should see this:

Hmm, before we get to mobilizing this application, let’s make the root url load the list of our posts instead of the default Rails index file:
rm public/index.html
Edit the config/routes.rb and set the root route like so:
Jqmoblog::Application.routes.draw do resources :posts root :to => "posts#index" end
Now load up http://localhost:3000 again and you should see the empty list of posts.
We still need to get the jQuery Mobile files on the page. Lets use the ones hosted on jquery.com. Add them to the application’s layout file so they’ll be on every page that gets served. In app/views/layouts/application.html.erb, edit the head section to look like this:
<head> <title>Jqmoblog</title> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" /> <%= javascript_include_tag :defaults %> <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script> <%= csrf_meta_tag %> </head>
Okay, everything is in place. Now we’re ready to turn this into a mobile app!
Getting Started
Before we flesh out our mobile CRUD actions, let’s get the posts index looking decent in mobile browsers. jQuery Mobile relies directly on the page’s markup to work its magic, so to invoke it we just need to change our views to conform to its conventions.
Each “page” in a jQuery Mobile application needs to be wrapped in a div with a data-role attribute of page. I put “page” in quotes because there can actually be many of them on a single webpage loaded from the server. In our app we’ll be loading each “page” from Rails, so we should just add this to our layout file which will wrap each of our individual views:
Before
<body> <%= yield %> </body>
After
<body>
<div data-role="page">
<%= yield %>
</div>
</body>
Next edit the post’s index (index.html.erb) and change the markup to create a header and a content section which lists all the posts in the database.
Before
<h1>Listing posts</h1>
<table>
<tr>
<th>Title</th>
<th>Body</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.body %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Post', new_post_path %>
After
<div data-role="header">
<h1>Listing posts</h1>
</div>
<div data-role="content">
<ul data-role="listview">
<% @posts.each do |post| %>
<li>
<%= link_to post.title, post %>
<%= link_to 'edit post', edit_post_path(post), "data-icon" => "gear" %>
</li>
<% end %>
</ul>
</div>
Load up the page and it should look like this:

Two things to note here. First, we are once again using the data-role attribute to create the header and the styled list. This is a major theme of jQuery Mobile (as of the Alpha, I’m told they *might* be switching to class names instead of data- attributes). Second, each list item has two links, and jQuery Mobile automatically knows that this means we want to use a split button list. Pretty cool, huh?
Let’s add a button which will take us to a page where we can create new posts. Add this line to the end of the header div:
<%= link_to 'Add', new_post_path, "data-icon" => "plus", "class" => "ui-btn-right" %>
Again, jQuery Mobile “just knows” that this should be a button in our header and we pass it a class and a data-icon attribute to tell it where to place it and which icon to use. We now have a button in the header which links to the new post path!

Create
We’re gonna need to create posts so we can read, update and delete them, so lets handle creation first. The “Add” button on the posts index links to the new.html.erb view. It works as is and looks okay too. We’ll just tweak the markup to make it fit into the jQuery Mobile styles:
<div data-role="header"> <h1>New Post</h1> </div> <div data-role="content"> <%= render 'form' %> </div>
We can now add new posts using the mobile interface! Go ahead and create a few so the posts index shows a list with links to edit each post:

Read
People will read posts from their show.html.erb view. Again, no change to the underlying controller or model code needs to happen. Just update the view file to look like this:
<div data-role="header"> <h1><%= @post.title %></h1> <%= link_to 'Home', posts_url, "class" => "ui-btn-right" %> </div> <div data-role="content"> <%= @post.body %> </div>

Update
When we set up the posts index we added links to the edit.html.erb view using the gear icon on the right side of the split list. Now we just need to change the markup on that view to conform to jQuery Mobile’s requirements. Have you sniffed out a pattern to this development process yet?
<div data-role="header"> <h1>Editing Post</h1> </div> <div data-role="content"> <%= render 'form' %> </div>
Again, it just works as expected and it will look great on many mobile devices. On to the final action, delete!
Delete
To facilitate deleting a post we just have to modify the delete links created by Rails’ scaffold generator to fit the rest of the mobile site. I think the edit page is a good place to add a delete link, so lets add a button to the header of edit.html.erb:
<%= link_to 'Delete', @post, :method => :delete, "data-icon" => "delete", "class" => "ui-btn-right" %>
The edit view is now complete, and it lets us update and delete our post.

Closing Up
If you’ve made it this far, you’ve probably realized that working with jQuery Mobile is pretty painless and it fits in with Rails quite well. There are a bunch of other things that jQuery Mobile can do, but this should hopefully whet your appetite. Remember, the framework is still in the Alpha stage so things can and probably will change.
I encourage you to read more about the project and get involved at an early stage so we can all benefit from a strong community!
***Download the source code for the application built in this post***
Jerod Santo is an Editor at Fuel Your Coding and a contract software developer at RSDi where he works daily with Ruby, JavaScript, and related technologies. He loves shiny toys, powerful tools, and open-source software. Learn more about Jerod by visiting his homepage or following him on Twitter.


A very amazing practise.
I want to know, is this post suit all types of mobile, or just for Iphone?
The jQuery Mobile team is committed to support a plethora of browsers by starting with a base of solid markup and progressively enhancing for more capable user agents.
More here: http://jquerymobile.com/gbs/
hey thnx for a this post…
since last couple of days I ‘ve started working on jQuery mobile
It would be nice if u can suggest to deal with ajax forms using jQuery mobile in RoR
thnx
After implement the code as instructed in the tutorial, I have encountered a problem. When I press the delete button on the Edit page, an error dialog will show up which said “error loading page” then index page will show up correctly.
This happen every time. Has anyone encounter this problem regarding delete?
I have same problem. Maybe someone know how to fix it?
I’m having the same problem, have you found a solution yet?
Thanks for the tutorial. Nice primer.
@paul – check you are loading rails.js correctly. The tutorial suggests using :defaults to load the JS, but I went with
If the jQuery version of the rails.js helpers dont load, the ajax delete wont work.
… oh, i went with code that got stripped out :-) anyhow, use: ‘jquery.min’, ‘rails’ in your rails js loading statement in your header.
Great post for start! Thanks!
In this case i need duplicate my view files to mobile version?
Is there a solution to create a new template file just?
Nice post. Clear and usefull. thnx!
awesome article. I would like to flattr you through flattr.com have you considered getting an account?
this article was really useful for me as I’m currently working on a mobile interface for a small app that uses rails as backend :)
to avoid ajax style requests, you should add a rel attribute to every link.
example: “external” %>
to make redirects work, add the javascript snippet as described in http://forum.jquery.com/topic/login-problems-with-redirects
thnx!
I have a Rails 3 application that is ready for Android, and jQuery looks like the right tool for the job. Thanks for the excellent write-up!
Thanks for the tutorial.. its very useful for me
this is amazing. many thanks!
I’ve appreciated very much your post.
I’ve tried the tutorial and is works !
I’ll start using jquery for my first RoR Mobile application.
I was wondering if you’d like make available the sources of the
stylesheet and javascripts to be included in the application header.
Thanks
Not seeing the correct CSS in your browser? You might need a different snippet for the header. Try using this snippet I found at the JQM web site:
MyAppTitle
This solution worked for me.
Thank you Jerod for introducing me to JQuery Mobie – I appreciate your effort to create together this very helpful tutorial.
Dan
Oops – the snippet didn’t show up in my comment!
Go to http://www.jquerymobile.com/download, and grab the copy/paste snippet if your CSS is not working properly.
Thanks Dan! The JQuery Mobile snippet provided by Jerod seems to not be working with 3.2. The one you provided works though.
Even this cud help http://jquerymobile.com/demos/1.0a1/docs/buttons/buttons-icons.html#buttons-grouped.html
BTW nice work Jerod Thanks.
FYI, I hope this saves someone a lot of time. On Rails 3.1, make sure you change the following in app/views/layouts/application.html.erb
with
Also, that just removed the errors I was getting. Updating to the latest Jquery Mobile release candidate to actually see any changes on pages (YMMV):
Jqmoblog
http://stackoverflow.com/questions/6433679/a-ruby-on-rails-bug-with-coffeescript
https://github.com/ryanb/nifty-generators/issues/131
When i create a post using your application, the home button does not work on the upper right. I have to manually refresh. anyone know whats causing this?
Great article.. i was looking for something like this. tks