Строка "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 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
'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
?