Neil Neil - 18 days ago 8
Ruby Question

How to toggle a Boolean attribute in a controller action

I have an action that simply toggles the

#active
attribute to the opposite boolean state:


  • If
    @blog.active == true
    then
    update
    it to inactive

  • If
    @blog.active == false
    then
    update
    it to active



I got the following custom action in a controller to work, but there has to be some Rails way to more elegantly do this:

class BlogsController < ApplicationController

...

def toggle_active
if @blog.active?
@blog.update(active: false)
else
@blog.update(active: true)
end
end

end


Is there a Rails way of updating a boolean attribute to the opposite boolean state?

Answer

There are two things here contributing to that sense of ugh you're getting from this piece of code:

  1. The elegance and brevity of the desired action (“toggle the active boolean”) does not match the elegance and brevity of the code.
  2. At a glance, it's not obvious what you're doing without “running the code” in your head (assuming the named method you have here is for S.O. sake, not actually a separate controller action).

The solution to both is a named method. I think it makes sense on the model, like this:

class Blog < ApplicationRecord
  def toggle_active!
    update active: !active
  end
end

# controller
@blog = Blog.find(1)
@blog.toggle_active!

It's now clear in both the model and the controller what is occurring because the name/label, toggle_active, is there to add that context and clarity. Further, the controller doesn't need to know too much about the implementation of the method, which allows Blog to change how that occurs in the future should it be necessary.

Comments