2

I have the following code in a controller action, which looks at a user, and changes a boolean value to the opposite value, so if the user is true then it becomes false, and vice versa:

  if current_user.enable_access
    current_user.update_attribute(:enable_access, false) 
  else
    current_user.update_attribute(:enable_access, true) 
  end

Is there a neater way of writing this?

6 Answers 6

7

How about using the toggle method that was specifically intended for this?

current_user.toggle(:enable_access)

If you want to add persistence in one character, there's also the toggle! method.

current_user.toggle!(:enable_access)
Sign up to request clarification or add additional context in comments.

1 Comment

toggle won’t save a record, while update_attribute does. toggle! is just a syntactic sugar, but yes, it is :)
6

In one line, if current_user.enable_access can be only true`false`:

current_user.update_attribute(:enable_access, !current_user.enable_access) 

3 Comments

Do you mean current_user.update_attribute(:enable_access, !current_user.enable_access) (note the !)
thats so pretty i might just fall to my knees and weep with joy. Thanks :)
Gareth, try to restrain yourself. You'll wear out your pants if that's your reaction every time you discover something cool about Ruby.
3

Here's something to meditate on:

false # => false
true # => true

!false # => true
!true # => false

foo = false # => false
!foo # => true
foo = !foo # => true

foo = nil # => nil
!foo # => true

foo = !nil # => true
foo = !false # => true

Notice !!, which is a convenient way to turn a value into a true/false:

foo = !!nil # => false
foo = !!false # => false

foo = 1 # => 1
!foo # => false
!!foo # => true

foo = 'a' # => "a"
!foo # => false
!!foo # => true

0 == 1 # => false
1 == 1 # => true

'a' == '' # => false
'a' == 'a' # => true

These are the building blocks for comparisons in Ruby.

Comments

3

While the answer by @Зеленый is absolutely correct I wondered, that there is no DRY way to accomplish such a silly task.

The problem is that true and false in Ruby are instances of different classes, TrueClass and FalseClass respectively. That said, one can not just switch the boolean value inplace.

But what we can imagine, mediating at update_attribute source? Probably this is a shortest way to accomplish your task (please, do not use it at home, it’s a joke after all.)

current_user.tap do |cu|
  cu.enable_access ^= true
end.save validate: false

I just reinvented toggle!, thanks @Dremni for pointing this out.

Comments

1

current_user.toggle!(:enable_access)

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-toggle-21

Comments

1

I believe the DRY way to accomplish it would be to use:

current_user.enable_access = !current_user.enable_access

Then you could just write a method on a model and call it from any controller.

user.rb

def enable_user_access
    self.enable_access = !self.enable_access
end

then calling it from a controller

current_user.enable_user_access

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.