代码之家  ›  专栏  ›  技术社区  ›  nfm

如何在Rails中提交布尔参数?

  •  64
  • nfm  · 技术社区  · 14 年前

    show_all 有价值的 true . 此值与模型没有关联。

    我的控制器正在将此参数分配给实例变量:

    @show_all = params[:show_all]
    

    然而, @show_all.is_a? String if @show_all == true 总是失败。

    Rails解析为布尔值的值是什么?如何明确指定我的参数是布尔值而不是字符串?

    9 回复  |  直到 14 年前
        1
  •  70
  •   nsantorello    13 年前

    如果你使用

    @show_all = params[:show_all] == "1"

    然后你就可以放弃了 ? true : false params[:show_all] == "1" 语句本身将求值为true或false,因此不需要三元运算符。

        2
  •  101
  •   ted    8 年前

    更新:Rails 5:

    ActiveRecord::Type::Boolean.new.deserialize('0')
    

    更新:Rails 4.2为此提供了公共API:

    ActiveRecord::Type::Boolean.new.type_cast_from_user("0") # false
    

    上一个答案:

    ActiveRecord在中维护真/假表示的列表 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/column.rb

    2.0.0-p247 :005 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean("ON")
    2.0.0-p247 :006 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean("F")
    

    这不是Rails的公共API的一部分,所以我将其包装到一个helper方法中:

    class ApplicationController < ActionController::Base
      private
    
      def parse_boolean(value)
        ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
      end
    end
    

    class ApplicationControllerTest < ActionController::TestCase
      test "parses boolean params" do
        refute ApplicationController.new.send(:parse_boolean, "OFF")
        assert ApplicationController.new.send(:parse_boolean, "T")
      end
    end
    
        3
  •  22
  •   Community Nick Dandoulakis    7 年前

    这个问题已经很老了,但是因为我遇到过这个问题好几次,并且不喜欢任何一个提出的解决方案,所以我自己入侵了一个允许使用多个字符串来解决这个问题的东西 是的 例如'yes'、'on'、't'和相反的false。

    Monkey修补类字符串,并添加一个方法将其转换为boolean,并将此文件放入 /config/initializers 正如这里所建议的: Monkey Patching in Rails 3

    class String
      def to_bool
        return true if ['true', '1', 'yes', 'on', 't'].include? self
        return false if ['false', '0', 'no', 'off', 'f'].include? self
        return nil
      end
    end
    

    请注意,如果值不是true或false的有效值,则返回nil。搜索不一样 ?paid=false (返回所有未支付的记录)超过 ?paid=

    Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?
    

    它非常整洁,有助于保持控制器/模型的整洁。

        4
  •  17
  •   Community Nick Dandoulakis    7 年前
    @show_all = params[:show_all] == "1" ? true : false
    

    编辑

    正如所指出的那样 here ,三元运算符不是必需的,因此可以是:

    @show_all = params[:show_all] == "1"

        5
  •  4
  •   benr75    14 年前

    您可以将您的平等声明更改为:

    @show_all == "true"
    

    如果希望它是布尔值,可以在string类上创建一个方法,将字符串转换为布尔值。

        6
  •  3
  •   Jeremy Burton    11 年前

    @show_all = params[:show_all]
    if @show_all.to_s == "true"
       # do stuff
    end
    

    不管Rails是以字符串“true”还是“false”的形式传递参数,还是以实际的TrueClass或FalseClass的形式传递参数,此测试都将始终有效。

        7
  •  1
  •   chaimann    8 年前

    另一种方法是只传递键而不传递值。虽然使用 ActiveRecord::Type::Boolean.new.type_cast_from_user(value)

    考虑以下几点: myapp.com/products?show_all=true 然后打字 show_all

    myapp.com/products?show_all=false myapp.com/products 会回来的。

    如果我想退回所有未开封的收藏品 myapp.com/products?all 在我的控制器里

    private
    
    def show_all?
      params.key?(:all)
    end
    

    如果键存在于params中,那么不管它的值是多少,我都知道我需要返回所有产品,而不需要类型转换值。

        8
  •  1
  •   mohamed-ibrahim    8 年前

    def show_all= value
      @show_all = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
    end
    
        9
  •  1
  •   Emad    5 年前

    你可以这么做

    @show_all = params[:show_all].downcase == 'true'
    
        10
  •  0
  •   fisherwebdev    12 年前

    您可以将所有布尔参数转换为实布尔值,如下所示:

    %w(show_all, show_featured).each do |bool_param|
      params[bool_param.to_sym] = params[bool_param.to_sym] == "true"
    end
    

    在此解决方案中,nil参数将变为false。

        11
  •  0
  •   ecoologic    5 年前

    活动模型 attribute

    class Model
      include ActiveModel::Attributes
    
      attribute :show_all, :boolean
    end
    
    Model.new(show_all: '0').show_all # => false
    

    可以看出 here .


    class Model
      include ActiveModel::Attributes
    
      attribute_reader :show_all
    
      def show_all=(value)
        @show_all = ActiveModel::Type::Boolean.new.cast(value)
      end
    end
    
    Model.new(show_all: '0').show_all # => false
    
        12
  •  0
  •   Shawn Deprey    4 年前

    虽然没有明确的问题是关于什么,但我觉得这是适当的相关;如果您试图在 钢轨试验 然后您需要以下语法。

    post :update, params: { id: user.id }, body: { attribute: true }.to_json, as: :json
    

    我到达这个线程是为了寻找这个语法,所以我希望它也能帮助寻找这个的人。贷记 Lukom