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.
Scenario
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 toggle_published
@banner.toggle! :published
end
2.- Define the member route to our new action
# config/routes.rb
# Others routes
resources :banners do
member do
post :toggle_published
end
end
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, toggle_published_banner_path(banner), remote: true, method: :post, title: t(:update_published) %>
</td>
</tr>
4.- Update the DOM with the new content and profit (?)
// app/views/banners/toggle_published.js.erb
$("#<%= dom_id(@banner) %> .published a").html("<%== @banner.published_icon %>")
Top comments (2)
published_icon
andupdate_published
aren't explained. How are they defined and what are they intended to do?sorry, that's an example from a real project i've made. Banner is a model with a method called published_icon, but can be replaced with any text yes or no. And the route is a member route to update the model itself