如何在Rails中提交布尔参数?
我正在提交值为true
的参数show_all
。 该值不与模型相关联。
我的控制器将这个参数分配给一个实例variables:
@show_all = params[:show_all]
但是, @show_all.is_a? String
@show_all.is_a? String
, if @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