33

This is really racking my brain, but maybe I'm trying to hard.

I'm passing a param via a URL (example.com?debug=true)

So I basically want to say:

if params[:debug] == true
 do xyz
else
 do abc
end

But for whatever reason that if statement just isn't doing like it seems like it should.

Is there a better way to do that if/else statement based on a param being true or false?

The debug param will either have a value of true, no value, or a value of false (as far as the URL goes).

Shpigford
  • 24,748
  • 58
  • 163
  • 252

5 Answers5

53

params come in as strings, so you need to compare against "true", not true.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • That was the problem...wasn't comparing as a string. – Shpigford Nov 10 '09 at 22:07
  • another solution is to check for it's presence `if params[:debug].present?` – SparK May 31 '16 at 14:28
  • @Dty For `nil` and `false` the method `.present?` returns `false`. It is the exact opposite of `.blank?`. – SparK Jul 18 '16 at 16:49
  • @SparK the answer here says params come in as strings. If `params[:debug]` is the string "false" it will be present (i.e. evaluated incorrectly). – Dty Jul 19 '16 at 05:02
  • @Dty in that case, yes... I'm not sure if the parameter will ever come as "false" or will simply be omitted... – SparK Jul 19 '16 at 12:53
  • Such a silly mistake. Was stuck on this for more than an hour. Thanks!! – Shreehari Nov 14 '21 at 18:31
36

You could use ActiveRecord's method of checking truthful values if you don't want to reinvent the wheel (this is what is used when passing params inside an ActiveRecord object

Rails 3-4.1

if ActiveRecord::ConnectionAdapters::Column.value_to_boolean(params[:debug])
    do xyz
else
    do abc

Rails 4.2.0

ActiveRecord::Type::Boolean.new.type_cast_from_database(params[:debug])

Rails 5

ActiveModel::Type::Boolean.new.cast(params[:debug])

Might be worth wrapping in a helper but never the less it's quite flexible:

rails c
Loading development environment (Rails 3.2.6)
1.9.3p194 :001 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean '1'
 => true 
1.9.3p194 :002 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean '0'
 => false 
1.9.3p194 :003 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean 1
 => true 
1.9.3p194 :004 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean true
 => true 
1.9.3p194 :005 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean 'true'
 => true 
1.9.3p194 :006 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean 'on'
 => true 
1.9.3p194 :007 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean 'off'

Custom extension

Some people frown on extending core classes but this does fit with the DRY principle.

# config/initializer/boolean.rb
class Boolean
  def self.parse(value)
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
  end
end

Then used like

if Boolean.parse(params[:debug])
  then xyz
toxaq
  • 6,745
  • 3
  • 46
  • 56
7

Since Rails/ActiveRecord 4.2.0 it is

if ActiveRecord::Type::Boolean.new.type_cast_from_user params[:debug]
  do xyz
else
  do abc
end

In Rails 5 it is:

if ActiveModel::Type::Boolean.new.cast params[:debug]
  do xyz
else
  do abc
end
Nathan
  • 1,762
  • 1
  • 20
  • 30
Jake
  • 126
  • 2
  • 3
5

But for whatever reason that if statement just isn't doing like it seems like it should.

I can almost guarantee that it is doing exactly what it should. When things don't make sense, one of our assumptions is wrong.

Is the value actually a boolean or is it string (or something else?). If the value is a string then of course the comparison to the boolean value true will fail. Try comparing to 'true' and see if that works.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • Contradictions do not exist. Whenever you think you are facing a contradiction, check your premises. You will find that one of them is wrong. (: – Terra Ashley Apr 18 '16 at 23:29
0

how about this?

params[:debug].to_s.downcase == 'true'
Gang Peng
  • 21
  • 3