This post details the process of changing my event tracking app to use javascript. The backend will still be handled by rails, but we want to change it so that the index and show views use some ajax to render additional details for an event. In addition, we’d like our views to render without having to use redirects for the create and update actions.
Active Model Serializer
We’re going to use active model serializer to help us convert our data into json objects. Let’s add the gem to our Gemfile to make it available to us.
then run bundle install so we can start to use it on the app.
We can now create a model serializer by running the generator in our terminal with rails generate serializer Event. This will create a new folder and ruby class file in app/serializers/event_serializer.rb.
We can add attributes to the event serializer which rails will use to return whatever object attributes you’d like. For my event model, the attributes I’m interested follow:
In order to properly serialize the object, I also need to create serializer classes for the User and Comment models with the rails generate command. Generating the user serializer is pretty straight forward, but the comments will need something more. The event has users attending it, but I also want event comments to also return the users who created the comment. I got it to return the correct values with this
Getting the Controller to Return JSON
Now to actually get our rails app to return a string formatted in json we need to change our events controller to spit back json from our events serializer.
I added similar logic to the show action. Now if I start up my rails server and navigate to localhost:3000/events.json, i’ll get something like this
Getting Views to Use JSON
We want our javascript to be run after the document loads and also between page loads without needing hard refreshes. I elected to go with a combination of document ready and page load functions to achieve this.
which calls my attachListeners function
The above code hijacks the submit button on the rails form with class="js-more". We can pass the value of the attribute data-id= number of the specific button that was pressed using the this keyword. Ajax gets called with $.get() with the arguments being a restful url that we build with the exact event object we want. When ajax receives a response (json from our serializer), we make some html elements by using js object notation and replace the html with the id #event-id-detail. Finally, it removes the button that was used to call the function.
Creating/Updating Events
Well that was okay, but we really want to use js objects and maybe use some prototype methods instead of manually writing out the new html elements in our javascript file. I’ll use Handlebars to help create html elements a little easier. Download handlebars.js and drop it into your asset pipeline. Let’s define our Event constructor
Now to build out an ajax function to convert to format that rails understands, then posts it the restful url, and define a function to do when it succeeds.
Now we can create a new object with var newObj = new Event(attributes), and then call a prototype method renderDiv with (which we’ll build later) with newObj.renderDiv. To do that, we’ll need the power of handlebars’ compiler. We’ll need to build out a template that we can use when a new event is returned by our controller. In our new event views, we stub out what our html will look like in script tag directly in our view.
Super important, the [[]] really should be curly braces.
The attributes in between the handlebars will get interpolated as the event attributes. To use the compiler, in our event.js file, we add in the document ready function
Now our app should be using ajax to create and update an event and render views without reloading!