Here we will explore a pattern that is useful for adding dynamic content to a Rails application. To enable this, we will make use of HTML5 data attributes and jQuery ajax requests in conjuction with our Rails application.
Let’s say we have a Rails app with a database of movies. Users can browse movies and those who have created an account can write reviews of a given movie. In the view for the
show action of the
Movies controller, we list out the director, year, and country of the movie. We also render a partial to display the movie’s reviews:
reviews partial displays the number of reviews, lists out the reviews, and provides a form that a logged in user can use to submit a review:
We would like to use ajax to submit this form, create a review, and dynamically update the content being displayed. Notice in the above snippet that we pass the form helper a
data hash with a key of
ajax_submit and a value corresponding to the parent container,
"reviews-container". The data attribute stores a reference to the element whose content we will update with the result of our ajax call.
I like to use data attributes to separate styling and business logic. Using class names to correspond with styling and data attributes to correspond to creation and display of data gives the developer a clear separation of concerns.
In the above snippet we use jQuery to attach a listener to the submission of the form. Since the partial containing the form will be changed dynamically, we use event delegation to attach the listener to the form’s parent container, which remains unchanged throughout the process. We prevent the form from navigating to a different page with
event.preventDefault(). We then extract the information we need to send to the controller and format it to pass to the ajax request. We make use of jQuery’s
post method to execute the request, passing it the appopriate arguments. The callback function reads the
ajax-submit data attribute from the form and uses that to replace the html of the corresponding container element with the response. Before the callback is invoked, though, the request will hit our
reviews.js that handles our request:
Notice that no values in the function are hard coded. All the information we need is stored in the data attributes of the HTML. The code does not reference specific class names that can change from element to element. This code is flexible and can be reused. If we have another situation where we want to send a post request and dynamically update a display, this code will handle it. All we have to do is assign the appropriate data attributes to the form and the container we want to update!