0

I want to set a default value if the variable is not set.

Here are valid values (which should not get overwritten): true false 0 1 "some string"

Here is how I'm currently trying to do this. Is this the right way?

  before_save :set_defaults

  def set_defaults
    self.is_approved = false if self.is_approved.nil?
  end

If this is indeed correct, is there a better syntax? In PHP we had isset() for this sort of stuff.

3
  • Looks like what you want is defined?. stackoverflow.com/questions/288715/… Commented Oct 31, 2011 at 10:42
  • you can try: if (!defined?(self.is_approved)) then Commented Oct 31, 2011 at 10:43
  • it looks well, though personally I prefer defaults to be set on initialization, it's more explicit and they pass validations: github.com/FooBarWidget/default_value_for Commented Oct 31, 2011 at 11:02

2 Answers 2

4

The idiomatic ruby version for this would be to write:

is_approved ||= false

which would set is_approved to false if is_approved is falsey: that means nil or false. Since setting to false if false is idempotent, it is not wrong.

Otherwise you could write:

is_approved = false unless is_approved.present?

which is identical to what you wrote:

is_approved = false if is_approved.nil?

but I find it slightly more readable. So yes: that is also the right way to do it.

You will notice that in ruby there are many ways to achieve the same thing. This is the part of programmer happiness: you choose which way suits you the best, and is most expressive at that place (because sometimes one is better suited, and sometimes the other). But for beginners it is sometimes confusing :)

Sign up to request clarification or add additional context in comments.

2 Comments

self.is_approved = !!is_approved will effectively do a Boolean cast, which will turn nil to false, leave false unchanged, leave true unchanged and turn any other truthy value to true.
@d11wtq: nice addition, but the OP also stated the is_approved can contain a string, which of course needs to remain. Secondly your statement will always do an assignment, which may or may not be the wanted effect (e.g. if counting the number of assignments or changing updated_at).
0

If you want to set a variable value of an object when it's unset (nil) and leave the actual value otherwise, you could do something shorter, like:

before_save :set_defaults

def set_defaults
  self.is_approved ||= false
end

6 Comments

That seems to break if my value is already false and I want to set some other default. For example if abc=false then abc ||= true will set it to true (even though we would want to keep the false value here).
a caveat: this won't work if you want to set true as default value, since x ||= true will turn a x=false into x=true
Is there any other simpler short hand available in ruby that would work in all cases?
it comes from OR operator: false || 5 => 5, nil || 5 => 5, in general !nil == !false
I guess in case of 'true' as a default value, you will have to test if it's nil. As it was suggested in the comment, you could use defined, but in this case self.is_approved.nil? == !defined(self.is_approved) and for me the first option is more natural, so for 'true' value I would leave the code as you presented it.
|

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.