There are occasions where we only have to update an attribute within a Rails model and in this case, change only one boolean from True to False or vice versa. To avoid having to enter the model form, check the checkbox, save and be redirected somewhere, it is easier if you implement a couple of lines of code to support toggle with the benefits of Ruby on Rails.


We have a model called Banner which has a boolean called published and we need to provide a easier interface to toggle that boolean from a list of banners

1.- Define a Controller action

We make use of an ActiveRecord::Base method called toggle!

# app/controllers/banners_controller.rb

def toogle_published
  @banner.toggle! :published

2.- Define the member route to our new action

# config/routes.rb

# Others routes
resources :banners do
  member do
    post :toogle_published

3.- Use Rails unobtrusive javascript to update the value

Suppose we have our index.html.erb file with a list of banners. We have to make sure of 2 things, include the helper dom_id and add a link to our new route using the remote option to do the request throught AJAX

# app/views/banners/index.html.erb

<tr id="<%= dom_id(banner) %>">
  <td class="published">
    <%= link_to banner.published_icon, toogle_published_banner_path(banner), remote: true, method: :post, title: t(:update_published) %>

4.- Update the DOM with the new content and profit (?)

// app/views/banners/toogle_published.js.erb

$("# <%= dom_id(@banner) %> .published a").html("<%== @banner.published_icon %>")

This post is also available on DEV.