如何值指派到Rails的ActiveRecord的布尔字段时,投? [英] How are values cast when assigning to a Boolean field in Rails ActiveRecord?

查看:182
本文介绍了如何值指派到Rails的ActiveRecord的布尔字段时,投?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短版我的问题

在Rails的ActiveRecord的,如果我有一个布尔领域,我给它分配类似 ABC 2 ,那么它就会立即转换为。该值 1 被转换为真正遗体为。为什么会出现这样的情况?我在哪里可以找到Rails文档(或Ruby文档),说明这种行为?

In Rails ActiveRecord, if I have a Boolean field and I assign it something like "abc" or 2, then it gets immediately cast to false. The value 1 is cast to true, and nil remains as nil. Why is this the case? Where can I find Rails documentation (or Ruby documentation) that explains this behavior?

我的问题的龙版

我难以理解的Rails如何处理尝试在Rails模型值分配给布尔字段。举例来说,假设我有一个有一个名为字符串字段网​​站模式:域名并称为布尔字段:can_ssl

I am having difficulty understanding how Rails handles attempts to assign values to a Boolean field in a Rails model. For example, let's say I have a Website model that has a String field called :domain and a Boolean field called :can_ssl.

我的迁移是这样的:

class CreateWebsites < ActiveRecord::Migration
  def change
    create_table :websites do |t|
      t.string :domain
      t.boolean :can_ssl, :default => false

      t.timestamps
    end
  end
end

在我的模型文件,我添加一些验证规则,所以它看起来是这样的:

In my model file, I add some validation rules, so it looks like this:

class Website < ActiveRecord::Base
  validates :domain, :presence => true
  validates :can_ssl, :inclusion =>  { :in => [true, false] }
end

就这么简单。基于我做了什么,我的希望:can_ssl 只能设置为值真实,没有别的。还有什么会导致是否有效?

Simple enough. Based on what I've done, I'm expecting that :can_ssl can only be set to the values true or false, and nothing else. Anything else would result in valid? being false.

但是,一旦我开始在控制台中打转转,我注意到,早在实际赋值语句,我提供的价值正在被改写为真正(或)。什么是管理一个价值如何被转换为规则的布尔

But once I start playing around in the console, I notice that, as early as the actual assignment statement, the value I provide is being recast to true or false (or nil). What are the rules governing how a value gets cast as a Boolean?

从控制台的例子:

w = Website.new
w.domain = 'stackoverflow.com'
w.can_ssl = true
w.can_ssl    # => true
w.valid?     # => true

w.can_ssl = nil
w.can_ssl    # => nil
w.valid?     # => false (so far so good)

w.can_ssl = 'abc'
w.can_ssl    # => false (How did 'abc' become the value false?)
w.valid?     # => true

w.can_ssl = 1
w.can_ssl    # => true (I guess it makes sense that 1 casts to true)
w.valid?     # => true

w.can_ssl = 2
w.can_ssl    # => false (But anything other than 1 casts to false?)
w.valid?     # => true

那么,根据什么我迄今所做的,我的认为的我可以得出以下结论:

So, based on what I've done so far, I think I can conclude the following:


  • 在当前分配值 1 真正布尔字段,该值将立即得到转换为真正,然后分配。

  • 当指定布尔字段,字段被实际分配

  • 当指定别的(如字符串或任意数量不是 1 ),则该值将立即得到转换为

  • When assigning the value 1 or true to a Boolean field, the value will immediately get cast as true and then assigned.
  • When assigning nil to a Boolean field, the field is actually assigned nil.
  • When assigning anything else (such as a String or any number that is not 1), then the value will immediately get cast as false.

难道我的理解是正确的?我缺少什么?

Am I understanding that correctly? Am I missing anything?

我很难找到文档中轨布尔字段类型,它可以给我澄清这一点。

I'm having difficulty finding documentation the Boolean field type in Rails which can give me clarification on this.

推荐答案

这是的ActiveRecord的肠子做:专门与

This is done in the bowels of ActiveRecord: specifically with

ActiveRecord::ConnectionAdapters::Column.value_to_boolean

至少在我的rails版本(可能是较新版本的地方略有不同)。

at least in my version of rails (it may be somewhere slightly different in more recent versions).

下面是源在我的版本

    # File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 144
    144:         def value_to_boolean(value)
    145:           if value.is_a?(String) && value.blank?
    146:             nil
    147:           else
    148:             TRUE_VALUES.include?(value)
    149:           end
    150:         end

在这里TRUE_VALUES被定义为

where TRUE_VALUES is defined as

#activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb:10:      
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set

1,0,f和t的有没有,因为流行的DBMS的如MySQL和放大器; PostgreSQL里,用来存储布尔变量为0/1,和f/T分别。

1, 0, "f" and "t" are there because of popular DBMS's like MySql & PostgreSql, which store bools as 0/1 and "f"/"t" respectively.

值得注意的是这之间的区别,什么传递一个如果中的Ruby / Rails,即是truthy或falsy值测试(falsy的价值观会失败的,如果考truthy值将通过它)。

It's worth noting the difference between this and what passes an "if" test in Ruby/Rails, ie values that are "truthy" or "falsy" ("falsy" values will fail an if test, "truthy" values will pass it).

在Ruby中,是falsy字面上的任何其他(包括0,空数组,空字符串,空哈希等)是truthy。所以,有什么之间被认为truthy一个巨大的差距/红宝石falsy,什么是保存为真/假为布尔数据库列。

In Ruby, nil and false are "falsy" and literally anything else (including 0, empty arrays, empty strings, empty hashes etc) is "truthy". So, there's a massive disparity between what is deemed truthy/falsy in ruby and what is saved as true/false to a boolean database column.

这篇关于如何值指派到Rails的ActiveRecord的布尔字段时,投?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆