Railsアプリケーションがあり、jQueryを使用してバックグラウンドで検索ビューを照会しています。 q
(検索語)、start_date
、end_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のような方法が必要だと思います!ありませんか...?
私が知る限り、文字列をブール値にキャストする方法は組み込まれていませんが、文字列が'true'
と'false'
のみで構成されている場合、メソッドを次のように短縮できます。
def to_boolean(str)
str == 'true'
end
ActiveRecordは、これを行うためのクリーンな方法を提供します。
def is_true?(string)
ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(string)
end
ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES
には、True値の明白な表現がすべて文字列として含まれています。
この答えは、そのままの形で、質問にあるものではなく、以下にリストされている他のユースケースにのみ適していることに注意してください。大部分は修正されていますが、多数の 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ファイルからの設定の読み込みとも互換性があります。
これを処理するための組み込みの方法はありません(ただし、アクションパックにはそのためのヘルパーがあります)。このようなことをアドバイスします
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
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
Rails 5では、ActiveRecord::Type::Boolean.new.cast(value)
を使用してブール値にキャストできます。
Wannabe_bool gemを使用できます。 https://github.com/prodis/wannabe_bool
このgemは、String、Integer、Symbol、およびNilClassクラスの#to_b
メソッドを実装します。
params[:internal].to_b
そのようなものは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
おそらくstr.to_s.downcase == 'true'
が完全性のためです。そうすれば、str
がnilまたは0でもクラッシュすることはありません。
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
Stringクラスに追加して、to_booleanのメソッドを作成できます。次に、「true」.to_booleanまたは「1」.to_booleanを実行できます。
class String
def to_boolean
self == 'true' || self == '1'
end
end
internal
をURLに追加することを検討してください。trueの場合、チェックボックスがオンになっていない場合は、params[:internal]
はnil
になり、falseと評価されます。 Rubyで。
私はあなたが使用している特定のjQueryに精通していませんが、URL文字列を手動で構築するよりも、あなたが望むものをきれいに呼び出す方法はありますか? $get
と$ajax
をご覧になりましたか?