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

Ruby on rails 如何在Rails中提交布尔参数?,ruby-on-rails,parsing,parameters,boolean,Ruby On Rails,Parsing,Parameters,Boolean,我正在提交一个参数show_all,其值为true。此值与模型不关联 我的控制器正在将此参数分配给实例变量: @show_all = params[:show_all] 但是,@show\u all.is\u a?字符串,如果@show_all==true总是失败 Rails将哪些值解析为布尔值?如何明确指定我的参数是布尔值而不是字符串?您可以将等式语句更改为: @show_all == "true" 如果希望它是布尔值,可以在string类上创建一个方法,将字符串转换为布尔值 @show_

我正在提交一个参数
show_all
,其值为
true
。此值与模型不关联

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

@show_all = params[:show_all]
但是,
@show\u all.is\u a?字符串
,如果@show_all==true总是失败


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

您可以将等式语句更改为:

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

@show_all = params[:show_all] == "1" ? true : false
如果您从复选框中传入值,这应该可以很好地工作——散列中缺少的键会生成nil,在条件语句中它的计算结果为false

编辑

如前所述,三元运算符不是必需的,因此它可以是:


@show\u all=params[:show\u all]==“1”

我想对Zettec的答案发表评论,但我还不能这样做,所以我会将此作为答案发布

如果你使用

@show_all=params[:show_all]=“1”


然后您可以删除
?true:false
因为
参数[:show_all]=“1”
语句本身将计算为true或false,因此不需要三元运算符。

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

%w(show_all, show_featured).each do |bool_param|
  params[bool_param.to_sym] = params[bool_param.to_sym] == "true"
end
Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?

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

这个问题已经很老了,但由于我多次遇到这个问题,并且不喜欢提出的任何解决方案,我自己就破解了一个允许使用多个字符串表示true,例如'yes'、'on'、't'以及表示false的相反字符串

Monkey修补类字符串,并添加一个方法将其转换为布尔值,然后将此文件放入
/config/initializers
,如下所示:

请注意,如果该值不是true或false的有效值,则返回nil。搜索
?paid=false
(返回所有未支付的记录)与搜索
?paid=
不同(我没有指定是否必须支付,所以放弃此选项)

然后,按照本例,控制器中的逻辑如下所示:

%w(show_all, show_featured).each do |bool_param|
  params[bool_param.to_sym] = params[bool_param.to_sym] == "true"
end
Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?
它非常整洁,有助于保持控制器/模型的清洁。

更新:Rails 5:

ActiveRecord::Type::Boolean.new.deserialize('0')
更新:Rails 4.2为此提供了公共API:

ActiveRecord::Type::Boolean.new.type_cast_from_user("0") # false
先前的答复:

ActiveRecord在中维护true/false表示的列表

这不是Rails公共API的一部分,因此我将其包装到了一个助手方法中:

class ApplicationController < ActionController::Base
  private

  def parse_boolean(value)
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
  end
end
class ApplicationController
并增加了一项基本测试:

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
class ApplicationControllerTest
我认为最简单的解决方案是根据“布尔”参数的字符串表示形式进行测试

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

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

另一种方法是只传递键而不传递值。虽然使用
ActiveRecord::Type::Boolean.new.Type\u cast\u from\u 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中,则无论其值如何,我都知道我需要返回所有产品,无需键入值。

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

def show_all= value
  @show_all = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
end
你可以这么做

@show_all = params[:show_all].downcase == 'true'

值得注意的是,如果要在Rails>5.2中将值传递给ActiveModel,更简单的解决方案是使用
属性

class Model
  include ActiveModel::Attributes

  attribute :show_all, :boolean
end

Model.new(show_all: '0').show_all # => false
可以看出


在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

虽然没有明确说明问题是关于什么的,但我觉得这是恰当的关联;如果您试图在rails测试中传递true boolean变量,则需要以下语法

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

我找到这个线程就是为了寻找这个语法,所以我希望它也能帮助寻找这个语法的人。值得赞扬的是,ruby中没有布尔值,只有当参数与模型关联时,
TrueClass
FalseClass
Rails仍然会自动计算出来-如果数据库中的列类型是布尔值,它会将参数视为
TrueClass
FalseClass
。你知道我如何能很好地做到这一点吗?可能是重复的,因为“基于参数为真或假的if/else语句是否有更好的方法来实现这一点?”的一个好解决方案可能也是这个的一个好解决方案。对于以后的参考,这是最清晰的答案。从技术上讲,布尔值可以作为“真”或“假”传递,但传递数字更好,因为它可以防止“真”==“真”等简单错误返回假。1或0。这是一个非常好的解决方案,干净整洁,为String类添加了真正有用的功能。非常好。恭喜你,你现在有了