Строка "true" и "false" для boolean


у меня есть приложение Rails, и я использую jQuery для запроса моего представления поиска в фоновом режиме. Есть поля q (поиска), start_date,end_date и internal. Элемент

13 82

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?

вы можете добавить в класс String метод to_boolean. Тогда вы можете сделать 'true'. to_boolean или '1'. to_boolean

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

Я удивлен, что никто не выложил это простое решение. То есть, если ваши строки будут "истинными" или "ложными".

def to_boolean(str)
    eval(str)
end