স্ট্রেিং "সত্য" এবং "মিথ্যা" বুলিয়ান


86

আমার একটি রেলস অ্যাপ্লিকেশন রয়েছে এবং আমি ব্যাকগ্রাউন্ডে আমার অনুসন্ধান ভিউটি জিজ্ঞাসা করতে jQuery ব্যবহার করছি। ক্ষেত্রগুলি q(অনুসন্ধান শব্দ) start_date, end_dateএবং internalinternalক্ষেত্রটিতে কোনও চেকবক্সটি এবং আমি ব্যবহার করছি 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]কারণ সেখানে একটি "স্ট্রিং" সত্য "বা" মিথ্যা "রয়েছে এবং এটি আমার বুলিয়ান করার জন্য প্রয়োজন। অবশ্যই আমি এটি এর মতো করতে পারি:

def to_boolean(str)
     return true if str=="true"
     return false if str=="false"
     return nil
end

তবে আমি মনে করি এই সমস্যাটি মোকাবেলার জন্য আরও একটি রুবি'শ উপায় থাকতে হবে! নেই তো ...?

উত্তর:


134

আমি যতদূর জানি বুলেটিয়ানদের জন্য কাস্টিং স্ট্রিংয়ের ক্ষেত্রে তেমন কোনও নির্মিত হয়নি, তবে যদি আপনার স্ট্রিংগুলি কেবলমাত্র থাকে 'true'এবং 'false'আপনি নিজের পদ্ধতিটি নীচে সংক্ষিপ্ত করতে পারতেন:

def to_boolean(str)
  str == 'true'
end

8
মাত্র একটি সামান্য পরিবর্তন str == 'সত্য' || str = '1'
এএমটুরকি

30
সম্পূর্ণতার জন্য সম্ভবত str.downcase == 'সত্য'
জেমাদডক্স

@ এএমটুরকি এটি আরআর == 'সত্য' হওয়া উচিত নয় str == '1' নিয়ে দুটি "=="?
পাসক্যাল

@ লরিডার হ্যাঁ! যদি ডিফল্ট চেক_বক্স ব্যবহার করা হয়।
7urkm3n

49

অ্যাক্টিভেকর্ড এটি করার একটি পরিষ্কার উপায় সরবরাহ করে।

def is_true?(string)
  ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(string)
end

ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES স্ট্রিং হিসাবে সত্য মানগুলির সুস্পষ্ট উপস্থাপনা রয়েছে।


16
এমনকি সহজ, কেবল ActiveRecord::ConnectionAdapters::Column.value_to_boolean(string)(উত্স) ব্যবহার করুন apidock.com/rails/v3.0.9/ActtiveRecord/ সংযোগ অ্যাডাপ্টারস
মাইক অ্যাটলাস

হ্যাঁ, সর্বশেষ সংস্করণে!
সত্য কল্লুরি

6
ActiveRecord::Type::Boolean.new.type_cast_from_user("true")=> সত্য ActiveRecord::Type::Boolean.new.type_cast_from_user("T")=> সত্য
অ্যালেক্স চ্যাফি

ভুয়া মান তালিকাকে অ্যাক্টিভমডেলে সরানো হয়েছে :: প্রকার ::
বেলিয়ানগুলিতে

ActiveModel::Type::Booleanঅনেক বেশি উপযুক্ত পাথের মতো মনে হচ্ছে - ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES"সত্যবাদী" মান থাকা সত্ত্বেও যে কেউ তর্ক করতে পারে যে এটি কেবল ঘটনাচক্রেই ঘটেছিল এবং যে মানগুলি সেই নির্দিষ্ট ব্যবহারের ক্ষেত্রে সত্যবাদী হিসাবে বিবেচিত হওয়া উচিত তবে অন্যকেও অন্তর্ভুক্ত করা যায় না। অন্যদিকে, ActiveModel::Type::Booleanদৃশ্যত জেনেরিক উপায়ে ব্যবহার করার জন্য ডিজাইন করা হয়েছে।
লিন্ডি সাইমন

24

সুরক্ষা বিজ্ঞপ্তি

মনে রাখবেন যে এই উত্তরটি খালি আকারে প্রশ্নের উত্তরের পরিবর্তে নীচে তালিকাভুক্ত অন্যান্য ব্যবহারের ক্ষেত্রে উপযুক্ত। বেশিরভাগ স্থির হয়ে থাকলেও, অনেকগুলি ওয়াইএএমএল সম্পর্কিত সুরক্ষিত দুর্বলতা রয়েছে যা ইউএমএল হিসাবে ওয়াইএমএল হিসাবে লোড করার কারণে হয়েছিল।


স্ট্রিংগুলিকে বলগুলিতে রূপান্তর করার জন্য আমি যে কৌশলটি ব্যবহার করি তা হ'ল 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বারগুলি কোডগুলির ভিতরে একবার স্ট্রিং হয়, config.etc.somethingএর মান স্ট্রিং হবে "false"এবং এটি ভুলভাবে মূল্যায়ন করবে true। তবে আপনি যদি এটি করেন:

config.etc.something = YAML.load(ENV['ETC_SOMETHING'])

সব ঠিক আছে। এটি জিম ফাইলগুলি থেকে লোডিং কনফিগারেশনের সাথেও সামঞ্জস্যপূর্ণ।


4
উত্তীর্ণ স্ট্রিং আপনার নিয়ন্ত্রণে থাকলে এটি ভাল good এই প্রশ্নের ক্ষেত্রে, প্রদত্ত মানগুলি ব্যবহারকারীর ব্রাউজার থেকে আসে এবং যেমন, সেগুলি অনিরাপদ হিসাবে বিবেচনা করা উচিত। ওয়াইএএমএল আপনাকে যে কোনও রুবি অবজেক্টকে সিরিয়ালাইজ / ডিসায়রিয়াল করার অনুমতি দেয় এবং এটি সম্ভাব্য বিপজ্জনক। অসংখ্য ঘটনা ঘটেছে: google.com/webhp?q=rails+yaml+vulnerability
তেওলা

4
@ টিউলাস, আমি আপনার সাথে পুরোপুরি একমত আসলে, আমি একটি নোটিশ যুক্ত করছি যাতে লোকেরা এটি কোনও সুরক্ষিত উপায়ে ব্যবহার না করে।
হালিল Özgür

16

এটি পরিচালনা করার জন্য কোনও অন্তর্নির্মিত উপায় নেই (যদিও এর জন্য অ্যাকশনপ্যাকের কোনও সহায়ক থাকতে পারে)। আমি এই জাতীয় কিছু পরামর্শ দিতে হবে

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

4
আপনি যদি "!! (s = ~ / regex_here /)" ব্যবহার করেন তবে আপনার "র" এবং ... গার্ডের দরকার নেই কারণ "শূন্য = ~ / কিছু /" শূন্য করে দেয়।
প্যাভলিং

আহ। আমি এটি যুক্ত করেছি তবে পুরাতনটিকেও রেখেছি, কারণ আমার কাছে মনে হয় .matchএটি পড়তে কিছুটা সহজ।
মার্সেল জ্যাকওয়ার্থ

7

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

4
এটি অ্যাক্টিভেকর্ড :: টাইপ করুন :: বেলিয়ান.নিউজকাস্ট (মান) রেল 5 এ (নীচে সিউইটি দেখুন)
ডেভ বার্ট

6

আপনি wannabe_bool রত্ন ব্যবহার করতে পারেন। https://github.com/prodis/wannabe_bool

এই রত্ন #to_bস্ট্রিং, পূর্ণসংখ্যা, সিম্বল এবং নীলক্লাস ক্লাসের জন্য একটি পদ্ধতি প্রয়োগ করে ।

params[:internal].to_b

6

5 রেলগুলিতে আপনি ActiveRecord::Type::Boolean.new.cast(value)এটিকে বুলিয়ানতে কাস্ট করতে ব্যবহার করতে পারেন ।


4
সচেতন থাকুন, অ্যাক্টিভেকর্ড :: টাইপ করুন :: বুলিয়ান.নিউকাস্ট ("42") সত্য প্রত্যাবর্তন করে
splitByZero

3

আমি রুবিতে অন্তর্নির্মিত এমন কিছুই ভাবি না। আপনি স্ট্রিং ক্লাসটি আবার খুলতে এবং সেখানে_বুল পদ্ধতিটি যুক্ত করতে পারেন:

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

তারপরে আপনি এটিকে আপনার প্রকল্পের যে কোনও জায়গায় ব্যবহার করতে পারেন: params[:internal].to_bool


4
আমি অবশ্যই কোনও to_boolফাংশন রিটার্ন চাইব না nil; এটা ভুল মনে হচ্ছে। অন্যান্য রূপান্তর ফাংশন এটি করে না: "a".to_iরিটার্ন দেয় 0, নাnil
ক্রাইজ


2

ভার্টাসের উত্স কোডটি দেখে আমি সম্ভবত এরকম কিছু করতে চাই:

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

1

internalযদি এটি সত্য হয় তবে আপনি কেবলমাত্র আপনার url এ সংযোজন বিবেচনা করতে পারবেন , যদি চেকবক্সটি চেক না করা হয় এবং আপনি সংযোজন না করেন তবে params[:internal]তা হবেnil রুবিতে মিথ্যা বলে মূল্যায়ন করে।

আপনি যে নির্দিষ্ট jQuery ব্যবহার করছেন তার সাথে আমি তেমন পরিচিত নই, তবে নিজে ইউআরএল স্ট্রিং তৈরির চেয়ে আপনি কী চান তা কল করার কি আরও পরিষ্কার উপায় আছে? আপনি কি একবার দেখেছেন $getএবং $ajax?


1

টুবুলিয়ান পদ্ধতিতে আপনি স্ট্রিং ক্লাসে যুক্ত করতে পারেন। তারপরে আপনি 'সত্য' টু_বুলিয়ান বা '1' টু_বুলিয়ান করতে পারেন

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

-5

আমি অবাক হয়েছি কেউ এই সহজ সমাধান পোস্ট করেনি। এটি যদি আপনার স্ট্রিংগুলি "সত্য" বা "মিথ্যা" হতে চলেছে।

def to_boolean(str)
    eval(str)
end

4
হ'ল কারণ এই সমাধানটি একটি সুরক্ষা বিপর্যয়। : ডি
ডেভিডব

4
এই সমাধানটির সাথে সমস্যাটি হ'ল ব্যবহারকারী ইনপুট - যদি কেউ টাইপ করে তবে to_boolean("ActiveRecord::Base.connection.execute('DROP TABLE *')")এটি আপনার ডাটাবেসটি ধ্বংস করে দেবে (এবং সত্য ফিরে আসবে!)। মজা করুন: ডি
বেন

ভাল দিক. আমি প্রসঙ্গে ভাবছিলাম না। আমি প্রয়োগ করার জন্য ন্যূনতম পরিমাণের চরিত্রটি ভাবছিলাম। :)
পোভেস

দুর্বলতার জন্য একটি সহজ সমাধান: bool = nil; bool = eval(str) if ["true", "false"].include?(str)কেবলমাত্র ভেবেছিলাম স্পষ্টির জন্য আমাকে যুক্ত করা উচিত।
ফার্নান্দো কর্ডেরিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.