web-dev-qa-db-ja.com

文字列「true」および「false」からブール値

Railsアプリケーションがあり、jQueryを使用してバックグラウンドで検索ビューを照会しています。 q(検索語)、start_dateend_date、およびinternalのフィールドがあります。 internalフィールドはチェックボックスであり、is(:checked)メソッドを使用して、クエリされるURLを作成しています。

$.getScript(document.URL + "?q=" + $("#search_q").val() + "&start_date=" + $("#search_start_date").val() + "&end_date=" + $("#search_end_date").val() + "&internal=" + $("#search_internal").is(':checked'));

今、私の問題はparams[:internal]にあります。「true」または「false」のいずれかを含む文字列があり、ブール値にキャストする必要があるためです。もちろん次のようにできます:

def to_boolean(str)
     return true if str=="true"
     return false if str=="false"
     return nil
end

しかし、この問題に対処するには、もっとRubyのような方法が必要だと思います!ありませんか...?

82
davidb

私が知る限り、文字列をブール値にキャストする方法は組み込まれていませんが、文字列が'true''false'のみで構成されている場合、メソッドを次のように短縮できます。

def to_boolean(str)
  str == 'true'
end
129
cvshepherd

ActiveRecordは、これを行うためのクリーンな方法を提供します。

def is_true?(string)
  ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(string)
end

ActiveRecord::ConnectionAdapters::Column::TRUE_VALUESには、True値の明白な表現がすべて文字列として含まれています。

47
Satya Kalluri

セキュリティ通知

この答えは、そのままの形で、質問にあるものではなく、以下にリストされている他のユースケースにのみ適していることに注意してください。大部分は修正されていますが、多数の YAML関連のセキュリティ脆弱性 があります。これは、ユーザー入力をYAMLとして読み込むことによって発生しました。


文字列をブールに変換するために私が使用するトリックは、 YAML.load 、例えば:

YAML.load(var) # -> true/false if it's one of the below

YAML bool は非常に多くの真実/偽の文字列を受け入れます:

y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

別のユースケース

次のような設定コードがあると仮定します。

config.etc.something = ENV['ETC_SOMETHING']

そしてコマンドラインで:

$ export ETC_SOMETHING=false

ENV varsは一度コード内の文字列であるため、config.etc.somethingの値は文字列"false"になり、trueと誤って評価されます。しかし、あなたがこれを好きなら:

config.etc.something = YAML.load(ENV['ETC_SOMETHING'])

それはすべて大丈夫でしょう。これは、.ymlファイルからの設定の読み込みとも互換性があります。

23
Halil Özgür

これを処理するための組み込みの方法はありません(ただし、アクションパックにはそのためのヘルパーがあります)。このようなことをアドバイスします

def to_boolean(s)
  s and !!s.match(/^(true|t|yes|y|1)$/i)
end

# or (as Pavling pointed out)

def to_boolean(s)
  !!(s =~ /^(true|t|yes|y|1)$/i)
end

同様に機能するのは、false/trueリテラルの代わりに0と非0を使用することです:

def to_boolean(s)
  !s.to_i.zero?
end
16

ActiveRecord::Type::Boolean.new.type_cast_from_userは、Railsの内部マッピングConnectionAdapters::Column::TRUE_VALUESおよびConnectionAdapters::Column::FALSE_VALUESに従ってこれを行います。

[3] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("true")
=> true
[4] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("false")
=> false
[5] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("T")
=> true
[6] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("F")
=> false
[7] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("yes")
DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` ("yes") to a boolean column. Currently this value casts to `false`. This will change to match Ruby's semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you should explicitly handle the values you would like cast to `false`. (called from <main> at (pry):7)
=> false
[8] pry(main)> ActiveRecord::Type::Boolean.new.type_cast_from_user("no")
DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` ("no") to a boolean column. Currently this value casts to `false`. This will change to match Ruby's semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you should explicitly handle the values you would like cast to `false`. (called from <main> at (pry):8)
=> false

したがって、次のようなイニシャライザで独自のto_b(またはto_boolまたはto_boolean)メソッドを作成できます。

class String
  def to_b
    ActiveRecord::Type::Boolean.new.type_cast_from_user(self)
  end
end
7
AlexChaffee

Rails 5では、ActiveRecord::Type::Boolean.new.cast(value)を使用してブール値にキャストできます。

5
CWitty

Wannabe_bool gemを使用できます。 https://github.com/prodis/wannabe_bool

このgemは、String、Integer、Symbol、およびNilClassクラスの#to_bメソッドを実装します。

params[:internal].to_b
5
Prodis

そのようなものはRubyに組み込まれているとは思いません。 Stringクラスを再度開き、そこにto_boolメソッドを追加できます。

class String
    def to_bool
        return true if self=="true"
        return false if self=="false"
        return nil
    end
end

その後、次のようにプロジェクトのどこでも使用できます:params[:internal].to_bool

3
socha23

おそらくstr.to_s.downcase == 'true'が完全性のためです。そうすれば、strがnilまたは0でもクラッシュすることはありません。

3
user1839842

Virtus のソースコードを見ると、次のようなことができます。

def to_boolean(s)
  map = Hash[%w[true yes 1].product([true]) + %w[false no 0].product([false])]
  map[s.to_s.downcase]
end
2
d11wtq

Stringクラスに追加して、to_booleanのメソッドを作成できます。次に、「true」.to_booleanまたは「1」.to_booleanを実行できます。

class String
  def to_boolean
    self == 'true' || self == '1'
  end
end
1
Josh Cavin

internalをURLに追加することを検討してください。trueの場合、チェックボックスがオンになっていない場合は、params[:internal]nilになり、falseと評価されます。 Rubyで。

私はあなたが使用している特定のjQueryに精通していませんが、URL文字列を手動で構築するよりも、あなたが望むものをきれいに呼び出す方法はありますか? $get$ajaxをご覧になりましたか?

1
Russell