developer tip

부울에 대한 문자열 "true"및 "false"

optionbox 2020. 9. 23. 07:32
반응형

부울에 대한 문자열 "true"및 "false"


Rails 애플리케이션이 있고 jQuery를 사용하여 백그라운드에서 내 검색보기를 쿼리하고 있습니다. 필드 q(검색어) start_date,, end_dateinternal. 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

하지만이 문제를 해결하기 위해서는 더 루비적인 방법이 있어야한다고 생각합니다! 거기 없나요 ...?


내가 아는 한 문자열을 부울로 캐스팅하는 방식은 없지만 문자열이 다음으로 만 구성 '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 관련 보안 취약점 이 있습니다.


문자열을 bool로 변환하는 데 사용하는 트릭은 다음 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

이제 ENVvars는 코드 내에서 한 번 문자열 이기 때문에 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레일 '내부 매핑이있어서 수행 ConnectionAdapters::Column::TRUE_VALUESConnectionAdapters::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

This gem implements a #to_b method for String, Integer, Symbol and NilClass classes.

params[:internal].to_b

In Rails 5 you can use ActiveRecord::Type::Boolean.new.cast(value) to cast it to a boolean.


I don't think anything like that is built-in in Ruby. You can reopen String class and add to_bool method there:

class String
    def to_bool
        return true if self=="true"
        return false if self=="false"
        return nil
    end
end

Then you can use it anywhere in your project, like this: params[:internal].to_bool


Perhaps str.to_s.downcase == 'true' for completeness. Then nothing can crash even if str is nil or 0.


Looking at the source code of Virtus, I'd maybe do something like this:

def to_boolean(s)
  map = Hash[%w[true yes 1].product([true]) + %w[false no 0].product([false])]
  map[s.to_s.downcase]
end

You could consider only appending internal to your url if it is true, then if the checkbox isn't checked and you don't append it params[:internal] would be nil, which evaluates to false in Ruby.

I'm not that familiar with the specific jQuery you're using, but is there a cleaner way to call what you want than manually building a URL string? Have you had a look at $get and $ajax?


You could add to the String class to have the method of to_boolean. Then you could do 'true'.to_boolean or '1'.to_boolean

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

I'm surprised no one posted this simple solution. That is if your strings are going to be "true" or "false".

def to_boolean(str)
    eval(str)
end

참고URL : https://stackoverflow.com/questions/8119970/string-true-and-false-to-boolean

반응형