Ruby-on-rails 如何在 Rails 中提交布尔参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3673607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I submit a boolean parameter in Rails?
提问by nfm
I'm submitting a parameter show_allwith the value true. This value isn't associated with a model.
我正在提交一个show_all值为的参数true。此值与模型无关。
My controller is assigning this parameter to an instance variable:
我的控制器正在将此参数分配给一个实例变量:
@show_all = params[:show_all]
However, @show_all.is_a? String, and if @show_all == truealways fails.
但是,@show_all.is_a? String和if @show_all == true总是失败。
What values does Rails parse as booleans? How can I explicitly specify that my parameter is a boolean, and not a string?
Rails 将哪些值解析为布尔值?如何明确指定我的参数是布尔值而不是字符串?
采纳答案by U?is Ozols
I wanted to comment on zetetic answer but as I can't do that yet I'll post this as an answer.
我想对 zetetic 的答案发表评论,但由于我无法做到这一点,因此我会将其发布为答案。
If you use
如果你使用
@show_all = params[:show_all] == "1"
@show_all = params[:show_all] == "1"
then you can drop ? true : falsebecause params[:show_all] == "1"statement itself will evaluate to true or false and thus ternary operator is not needed.
那么您可以删除,? true : false因为params[:show_all] == "1"语句本身将评估为真或假,因此不需要三元运算符。
回答by Wojtek Kruszewski
UPDATE: Rails 5:
更新:Rails 5:
ActiveRecord::Type::Boolean.new.deserialize('0')
UPDATE: Rails 4.2 has public API for this:
更新:Rails 4.2 为此提供了公共 API:
ActiveRecord::Type::Boolean.new.type_cast_from_user("0") # false
PREVIOUS ANSWER:
以前的答案:
ActiveRecord maintains a list of representations for true/false in https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/column.rb
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")
This is not part of Rails' public API, so I wrapped it into a helper method:
这不是 Rails 公共 API 的一部分,所以我将它封装到一个辅助方法中:
class ApplicationController < ActionController::Base
private
def parse_boolean(value)
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
end
and added a basic test:
并添加了一个基本测试:
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
回答by ismriv
This question is rather old, but since I came across this issue a couple of times, and didn't like any of the solutions proposed, I hacked something myself which allows to use multiple strings for truesuch as 'yes', 'on', 't' and the opposite for false.
这个问题很老了,但是由于我遇到过这个问题几次,并且不喜欢提出的任何解决方案,所以我自己破解了一些允许使用多个字符串为真的东西,例如“是”,“开” , 't' 和 false 相反。
Monkey patch the class String, and add a method to convert them to boolean, and put this file in /config/initializersas suggested here: Monkey Patching in Rails 3
Monkey 修补类 String,并添加一个方法将它们转换为布尔值,并/config/initializers按照此处的建议放入此文件:Rails 3 中的 Monkey Patching
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
Notice that if the value is none of the valid ones either for true or false, then it returns nil. It's not the same to search for ?paid=false(return all records not paid) than ?paid=(I don't specify if it has to be paid or not -- so discard this).
请注意,如果该值不是 true 或 false 的有效值,则它返回 nil。搜索?paid=false(返回所有未支付的记录)与搜索?paid=(我没有指定是否必须支付 - 所以丢弃它)不同。
Then, following this example, the logic in your controller would look like this:
然后,按照此示例,控制器中的逻辑将如下所示:
Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?
It's pretty neat, and helps to keep controllers/models clean.
它非常整洁,有助于保持控制器/模型清洁。
回答by zetetic
@show_all = params[:show_all] == "1" ? true : false
This should work nicely if you're passing the value in from a checkbox -- a missing key in a hash generates nil, which evaluates to false in a conditional.
如果您从复选框传递值,这应该会很好地工作 - 散列中缺少的键会生成 nil,在条件下评估为 false。
EDIT
编辑
As pointed out here, the ternary operator is not necessary, so this can just be:
正如这里所指出的,三元运算符不是必需的,所以这可以是:
@show_all = params[:show_all] == "1"
@show_all = params[:show_all] == "1"
回答by benr75
You could change your equality statement to:
您可以将平等声明更改为:
@show_all == "true"
If you want it to be a boolean you could create a method on the string class to convert a string to a boolean.
如果你希望它是一个布尔值,你可以在字符串类上创建一个方法来将字符串转换为布尔值。
回答by Jeremy Burton
I think the simplest solution is to test "boolean" parameters against their String representation.
我认为最简单的解决方案是针对它们的字符串表示测试“布尔”参数。
@show_all = params[:show_all]
if @show_all.to_s == "true"
# do stuff
end
Regardless of whether Rails delivers the parameter as the String "true" or "false" or an actual TrueClass or FalseClass, this test will always work.
无论 Rails 将参数作为字符串“true”或“false”还是实际的 TrueClass 或 FalseClass 传递,此测试始终有效。
回答by chaimann
Another approach is to pass only the key without a value. Although using ActiveRecord::Type::Boolean.new.type_cast_from_user(value)is pretty neat, there might be a situation when assigning a value to the param key is redundant.
另一种方法是只传递没有值的键。尽管 usingActiveRecord::Type::Boolean.new.type_cast_from_user(value)非常简洁,但可能存在为 param 键分配值是多余的情况。
Consider the following:
On my products index view by default I want to show only scoped collection of products (e.g. those that are in the stock). That is if I want to return all the products, I may send myapp.com/products?show_all=trueand typecast the show_allparameter for a boolean value.
考虑以下事项: 默认情况下,在我的产品索引视图中,我只想显示范围内的产品集合(例如,库存中的产品)。也就是说,如果我想返回所有产品,我可以发送myapp.com/products?show_all=true和类型转换show_all布尔值的参数。
However the opposite option - myapp.com/products?show_all=falsejust makes no sense since it will return the same product collection as myapp.com/productswould have returned.
然而,相反的选项 -myapp.com/products?show_all=false只是没有意义,因为它将返回与返回的相同的产品集合myapp.com/products。
An alternative:
替代:
if I want to return the whole unscoped collection, then I send myapp.com/products?alland in my controller define
如果我想返回整个无作用域集合,那么我发送myapp.com/products?all并在我的控制器中定义
private
def show_all?
params.key?(:all)
end
If the key is present in params, then regardless of its value, I will know that I need to return all products, no need to typecast value.
如果键存在于 params 中,那么无论它的值如何,我都会知道我需要返回所有产品,不需要对值进行类型转换。
回答by mohamed-ibrahim
You can add the following to your model:
您可以将以下内容添加到您的模型中:
def show_all= value
@show_all = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
回答by Emad
You could just do
你可以做
@show_all = params[:show_all].downcase == 'true'
回答by ecoologic
It's worth noting that if you're passing down a value to an ActiveModelin Rails > 5.2, the simpler solution is to use attribute,
值得注意的是,如果您将值传递给Rails > 5.2 中的ActiveModel,则更简单的解决方案是使用attribute,
class Model
include ActiveModel::Attributes
attribute :show_all, :boolean
end
Model.new(show_all: '0').show_all # => false
As can be seen here.
可以在这里看到。
Before 5.2 I use:
在 5.2 之前我使用:
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

![Ruby-on-rails 更新记录 rails 4 没有路由匹配 [PATCH]](/res/img/loading.gif)