如何值指派到Rails的ActiveRecord的布尔字段时,投? [英] How are values cast when assigning to a Boolean field in 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
ortrue
to aBoolean
field, the value will immediately get cast astrue
and then assigned. - When assigning
nil
to aBoolean
field, the field is actually assignednil
. - When assigning anything else (such as a
String
or any number that is not1
), then the value will immediately get cast asfalse
.
难道我的理解是正确的?我缺少什么?
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屋!