Строка "true" и "false" для boolean
у меня есть приложение Rails, и я использую jQuery для запроса моего представления поиска в фоновом режиме. Есть поля q (поиска), start_date,end_date и internal. Элемент
13 ответов:
насколько я знаю, нет встроенного способа приведения строк к булевым значениям, но если ваши строки состоят только из
'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имеет все очевидные представления истинных значений в виде строк.
Примечание
обратите внимание, что этот ответ в его голой форме подходит только для другого варианта использования, указанного ниже, а не для вопроса. В то время как в основном фиксированной, были многочисленные уязвимости безопасности, связанные с YAML которые были вызваны загрузкой пользовательского ввода в виде YAML.
трюк, который я использую для преобразования строк в bools является
YAML.load, например:YAML.load(var) # -> true/false if it's one of the belowYAML 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вот так
ENVvars-это строки, находящиеся внутри кода,config.etc.something's значение будет строка"false"и это будет неправильно оцениватьtrue. Но если вам это нравится:config.etc.something = YAML.load(ENV['ETC_SOMETHING'])все будет хорошо. Это совместимо с загрузкой конфиг от .YML файлы, а также.
нет никакого встроенного способа, чтобы справиться с этим (хотя actionpack может иметь помощника для этого). Я бы посоветовал что-то вроде этого
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что работает, так это использовать 0 и не-0 вместо ложных / истинных литералов:
def to_boolean(s) !s.to_i.zero? end
ActiveRecord::Type::Boolean.new.type_cast_from_userделает это в соответствии с внутренними сопоставлениями рельсов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
вы можете использовать wannabe_bool gem. https://github.com/prodis/wannabe_bool
этот камень реализует a
#to_bметод для классов String, Integer, Symbol и NilClass.params[:internal].to_b
в Rails 5 Вы можете использовать
ActiveRecord::Type::Boolean.new.cast(value)чтобы привести его к логическому значению.
Я не думаю, что что-то подобное встроено в 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
глядя на исходный код 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
возможно
str.to_s.downcase == 'true'для полноты. Тогда ничто не может разбиться, даже еслиstrравно нулю или 0.
вы можете рассмотреть только добавление
internalк вашему url, если это правда, то если флажок не установлен и вы не добавляете егоparams[:internal]будетnil, который оценивается как false в Ruby.Я не так хорошо знаком с конкретным jQuery, который вы используете, но есть ли более чистый способ вызвать то, что вы хотите, чем вручную построить строку URL? Вы уже посмотрели на
$getи$ajax?