True、boolean false、文字列 "true"、または文字列 "false"の4つのうちの1つになる値があります。文字列の場合はブール値に変換します。それ以外の場合は変更しないでください。言い換えると:
「真」が真になるはず
"false"はfalseになるはずです
真実であり続けるべき
falseはfalseのままになります
def true?(obj)
obj.to_s.downcase == "true"
end
Rails 5を使用している場合は、ActiveModel::Type::Boolean.new.cast(value)
を実行できます。
Rails 4.2ではActiveRecord::Type::Boolean.new.type_cast_from_user(value)
を使います。
Rails 4.2のように、真の値と偽の値がチェックされるので、動作はわずかに異なります。 Rails 5では、falseの値のみがチェックされます - 値がnilでないかfalseの値と一致しない限り、trueと見なされます。偽の値は両方のバージョンで同じです:FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]
Rails 5のソース: https://github.com/Rails/rails/blob/5-1-stable/activemodel/lib/active_model/type/boolean.rb
私は頻繁にこのパターンを使ってRubyの中心的な振る舞いを拡張して任意のデータ型をブール値に変換することをより簡単にするようにしました。
class String
def to_boolean
ActiveRecord::Type::Boolean.new.cast(self)
end
end
class NilClass
def to_boolean
false
end
end
class TrueClass
def to_boolean
true
end
def to_i
1
end
end
class FalseClass
def to_boolean
false
end
def to_i
0
end
end
class Integer
def to_boolean
to_s.to_boolean
end
end
それでは、パラメータfoo
があるとしましょう。
たくさんの条件文を使う代わりに、foo.to_boolean
を呼び出すだけで、残りの魔法を使うことができます。
Railsでは、このパターンは非常に一般的なので、ほとんどすべてのプロジェクトでこれをcore_ext.rb
という名前のイニシャライザに追加します。
## EXAMPLES
nil.to_boolean == false
true.to_boolean == true
false.to_boolean == false
0.to_boolean == false
1.to_boolean == true
99.to_boolean == true
"true".to_boolean == true
"foo".to_boolean == true
"false".to_boolean == false
"TRUE".to_boolean == true
"FALSE".to_boolean == false
"0".to_boolean == false
"1".to_boolean == true
true.to_i == 1
false.to_i == 0
if value.to_s == 'true'
true
elsif value.to_s == 'false'
false
end
h = { "true"=>true, true=>true, "false"=>false, false=>false }
["true", true, "false", false].map { |e| h[e] }
#=> [true, true, false, false]
考えすぎないでください。
bool_or_string.to_s == "true"
そう、
"true".to_s == "true" #true
"false".to_s == "true" #false
true.to_s == "true" #true
false.to_s == "true" #false
大文字が気になる場合は、「。downcase」を追加することもできます。
私はハッシュアプローチが好きですが(これまで私は似たようなことに使っていましたが)、真の値のマッチングにだけ気を配っています。
value = [true, 'true'].include?(value)
または他の値が真実と見なされる可能性がある場合
value = [1, true, '1', 'true'].include?(value)
元のvalue
が大文字と小文字を混在させる可能性がある場合は、他の処理を行う必要があります。
value = value.to_s.downcase == 'true'
しかし、もう一度、あなたの問題についてのあなたの特定の説明のために、あなたはあなたの解決策としてその最後の例を回避することができます。
Railsでは、他の回答で述べたようにActiveModel::Type::Boolean.new.cast(value)
を使うのが好きです。
しかし私が普通のRuby libを書くとき。それから私はJSON.parse
(標準のRubyライブラリ)が文字列 "true"をtrue
に、そして "false"をfalse
に変換するハックを使います。例えば。:
require 'json'
Azure_cli_response = `az group exists --name derrentest` # => "true\n"
JSON.parse(Azure_cli_response) # => true
Azure_cli_response = `az group exists --name derrentesttt` # => "false\n"
JSON.parse(Azure_cli_response) # => false
ライブアプリケーションからの例:
require 'json'
if JSON.parse(`az group exists --name derrentest`)
`az group create --name derrentest --location uksouth`
end
ruby 2.5.1で確認済み
私はこれを少しハックしました。 JSON.parse('false')
はfalse
を返し、JSON.parse('true')
はtrueを返します。しかし、これはJSON.parse(true || false)
では動作しません。ですから、もしあなたがJSON.parse(your_value.to_s)
のようなものを使うのであれば、それはあなたの目標を簡単だがハックな方法で達成するはずです。
https://rubygems.org/gems/to_bool のようなgemを使うことができますが、正規表現や三項を使って簡単に一行で書くことができます。
正規表現の例:
boolean = (var.to_s =~ /^true$/i) == 0
三項の例:
boolean = var.to_s.eql?('true') ? true : false
正規表現方式の利点は、正規表現が柔軟であり、さまざまなパターンに一致できることです。たとえば、varが "True"、 "False"、 'T'、 'F'、 't'、または 'f'のいずれかである可能性があると思われる場合は、正規表現を変更できます。
boolean = (var.to_s =~ /^[Tt].*$/i) == 0
Rails 5.1アプリでは、私はActiveRecord::Type::Boolean
の上に構築されたこのコアエクステンションを使います。 JSON文字列からブール値をデシリアライズすると、私にとっては完璧に機能します。
https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
# app/lib/core_extensions/string.rb
module CoreExtensions
module String
def to_bool
ActiveRecord::Type::Boolean.new.deserialize(downcase.strip)
end
end
end
コア拡張を初期化する
# config/initializers/core_extensions.rb
String.include CoreExtensions::String
rspec
# spec/lib/core_extensions/string_spec.rb
describe CoreExtensions::String do
describe "#to_bool" do
%w[0 f F false FALSE False off OFF Off].each do |falsey_string|
it "converts #{falsey_string} to false" do
expect(falsey_string.to_bool).to eq(false)
end
end
end
end
Railsでは、以前に次のようなことをしました。
class ApplicationController < ActionController::Base
# ...
private def bool_from(value)
!!ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
end
helper_method :bool_from
# ...
end
データベースに対してRailsが行うのと同じ方法で、ブール値の文字列の比較を一致させようとしている場合、これは素晴らしいことです。