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

我正在提交值为true的参数show_all 。 该值不与模型相关联。

我的控制器将这个参数分配给一个实例variables:

 @show_all = params[:show_all] 

但是, @show_all.is_a? String @show_all.is_a? Stringif @show_all == true总是失败。

Railsparsing为什么值为布尔值? 我如何显式指定我的参数是一个布尔值,而不是一个string?

我想评论zetetic的答案,但因为我不能这样做,但我会张贴这个答案。

如果你使用

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

那么你可以放弃? true : false ? true : false因为params[:show_all] == "1"语句本身将评估为true或false,因此不需要三元运算符。

更新: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的一部分,所以我把它包装成一个辅助方法:

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

并添加了一个基本testing:

 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 

这个问题是相当古老的,但由于我偶然遇到这个问题,并不喜欢任何提出的解决scheme,我自己砍了一些东西,允许使用多个string为真如 “是”,“上” ,'t'和相反的假。

猴子修补类string,并添加一个方法将其转换为布尔值,并将此文件放在/config/initializers如下所示: 在Windows 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 (返回所有没有付费的logging)比?paid= (我没有说明是否必须支付 – 所以放弃这一点)是不一样的。

然后,按照这个例子,你的控制器的逻辑看起来像这样:

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

这是相当整洁,并有助于保持控制器/模型清洁。

 @show_all = params[:show_all] == "1" ? true : false 

这应该很好地工作,如果你从一个checkbox中传递值 – 一个散列中缺less的键生成零,在条件中计算为false。

编辑

正如这里指出的那样,三元运算符是没有必要的,所以这可以是:

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

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

 @show_all == "true" 

如果你想要它是一个布尔值,你可以在string类上创build一个方法来将string转换为布尔值。

我认为最简单的解决scheme是testing“布尔”参数对他们的string表示。

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

不pipeRails是以string“true”还是“false”还是实际的TrueClass或FalseClass来传递参数,这个testing总是会起作用的。

你可以把你所有的布尔参数转换成这样的真正的布尔值:

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

在这个解决scheme中,零参数将变成错误的。

收集一切在一个ruby课堂: https : //gist.github.com/attenzione/a7ffe04ca28c57ffaa14

另一种方法是只传递没有价值的密钥。 尽pipe使用ActiveRecord::Type::Boolean.new.type_cast_from_user(value)是相当整洁的,但是当为param键值赋值是多余的时候可能会出现这种情况。

考虑以下几点:在默认情况下,我的产品索引视图中,我只想显示范围内的产品集合(例如库存中的产品)。 这就是说,如果我想返回所有的产品,我可以发送myapp.com/products?show_all=true并为myapp.com/products?show_all=true参数指定一个布尔值。

然而,相反的select – myapp.com/products?show_all=false只是没有意义,因为它将返回myapp.com/products将返回相同的产品集合。

替代:

如果我想返回整个myapp.com/products?all集合,那么我发送myapp.com/products?all并在我的控制器中定义

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

如果密钥存在于参数中,那么不pipe它的值如何,我都会知道我需要返回所有的产品,不需要types值。

您可以将以下内容添加到您的模型中:

 def show_all= value @show_all = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) end