This is a tutorial for ajax use with Rails conventions. For illustrative purposes, we’ll build a single-page task list app. For reference and convenience, I have created 2 github repos:
Static Task List: A textbook example on creating a basic and static task list. It also serves the purpose of demonstrating an app with excess navigation that can be significantly improved with ajax for an enhanced user experience.
Rai-jax: This tutorial serves an illustrative example of the significant improvement a little ajax and some styling can provide to an otherwise dull and static app.
Setup
You can use the Static Task List repo as a starting point for this tutorial. To do so, some initial setup is necessary:
The project is missing a database.yml file. This file specifies the configuration for your database, it is necessary to interact and save to the db. Copy the following yaml file into your config folder.
```yaml #database.yml development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 ```
Once the database.yml file is in the config folder, we then need to create the database. Normally to do this we would input the command
bundle exec rake db:migrate
, but we would like to have some initial data inside our database. That data is listed in the seeds.rb file under the db folder. To create the database and add this seed data, run the following command:``` bundle exec rake db:setup ```
- The last thing to do is to delete the contents of the tasks_controller.rb file. It’s best to start from scratch, we’ll be adding content into this file as we go along.
About Ajax
Ajax (Asynchronous JavaScript and XML) is used as a mechanism for sending and retrieving data asynchronously (in the background). While XML can certainly be used with ajax, it is not limited to this format. The JSON format, for example, is more commonly used today, especially in the Rails community. There are significant advantages in using Ajax, which include better user interactivity. Ajax allows content on a page to be updated without having to re-render the entire page, making it a “seamless” experience.
Part One: Creating a New Task on the Index Page
Before we start, let’s take a quick look at our schema so that we know what we’re working with:
1 2 3 4 5 6 7 8 9 10 11 |
|
After creating a Task model and then creating some tasks to play with, our Task Controller should look like this:
1 2 3 4 5 6 7 8 |
|
Instead of creating new.html.erb, let’s add a button somewhere on our index.html.erb that users can use to display a hidden form:
1 2 3 4 5 6 7 |
|
Using remote: true
option allows us to submit this form with ajax. This will disable the default Rails mechanism that would have otherwise navigated us to /tasks/new.
Before moving on, let’s quickly revisit our Task Controller and set it up to create new tasks with ajax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
I have removed the index action because I created a before_action
filter that creates the @tasks
instance variable for us automatically. Because we no longer have any logic in our index action, it is not necessary. Rails will automatically render the correct template, even without the presence of the action.
Noteworthy here is the respond_to
method invoked near the top that will allow us to render both html and javascript responses with all of our controller actions. The respond_to
method provides the ability to respond to the requests with many formats(i.e. csv, xml, etc…). This can be done for one or all actions in a controller. If we wanted to provide json only in our index action, we would write something like this:
1 2 3 4 5 6 7 8 |
|
Now, choose a place on the index page to hide your form by passing a style attribute with the following:
1 2 3 4 5 6 |
|
which will hide our form when the page is initially visited.
Next, create new.js.erb:
1 2 3 4 |
|
This is just an ERB template that generates Javascript instead of the HTML we’re used to. The js.erb files we create will go under the view folder associated with the controller we are working with, in this case /views/tasks .The file above basically translates to: “Find the element with an id attribute of task-form and at that point render the html in the form partial.” We typically do this in new.html.erb with:
1
|
|
Since render
is a Rails method, JavaScript doesn’t understand it and it has to be interpreted with ERB. The ‘j’ is syntactic sugar for <%= escape_javascript (render 'form') %>
1 2 3 4 5 6 7 |
|
This is the ‘form’ being rendered in new.js.erb with a remote: true
option being passed in. In our form partial, we also pass the remote: true
option that will execute an ajax POST request.
POST Request without Ajax:
POST request with Ajax:
Finally, we can wrap things up by rendering our new task list and hiding our form. This final step includes identifying where to render our list. Using the rai-jax app as an example, let’s look at what our final index.html.erb should look like at this stage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
And we update our task list and hide our form with create.js.erb:
1 2 3 4 |
|
Part Two: Updating a Task on the Index Page
As in Part One, let’s start by visiting our Task Controller and setting it up for updates:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Similar to Part One, we add an edit button with a remote: true
option
1 2 3 4 5 6 7 8 9 |
|
And, finally, our edit.js.erb and update.js.erb are the same as our new and update templates: edit.js.erb corresponds to new.js.erb and create.js.erb corresponds to update.js.erb.
Part Three: Deleting a Task on the Index Page
Our final updates to our Task Controller involves us providing the destroy action:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
When adding our delete button, two additional steps are required:
1 2 3 4 5 6 7 8 9 |
|
First, we pass in a method: :delete
option; Second, we provide a courtesy confirmation to the user making sure they don’t delete anything by accident.
The last file we’ll create is destroy.js.erb and it will contain one line:
1 2 3 |
|
Conclusion
Seriously, Rails makes ajax easy. As I mentioned above, there’s a repo of this up on GitHub with all the styling I omitted for brevity and clarity here. They’re small touch ups from the static list app, but go a long way in significantly improving look, feel, and user experience.