Rails 3 SQLite3 布尔假 [英] Rails 3 SQLite3 Boolean false

查看:41
本文介绍了Rails 3 SQLite3 布尔假的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 SQLite3 表中插入一个假布尔值,但它总是插入一个真值.

I'm trying to insert a false boolean value in a SQLite3 table but it always inserts a true value.

这是我的迁移:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :name, :string
      t.column :active, :boolean, :default => false, :null => false
    end
  end

  def self.down
    drop_table :resources
  end
end

当我尝试使用 rails 插入时,它会生成以下 SQL:

When I try to insert using rails it produces the following SQL:

INSERT INTO "users" ("name", "active") VALUES ('test', 'f')

SQLite 将 'f' 视为 true,因此它会将 true 插入到我的数据库中.我希望它生成的查询是:

SQLite treats 'f' as true so it inserts true into my database. The query I want it to generate is:

INSERT INTO "users" ("name", "active") VALUES ('test', false)

我做错了什么?

导轨:3.0.7

sqlite3 gem: 1.3.3

sqlite3 gem: 1.3.3

推荐答案

SQLite 使用 1 表示 true 和0 表示假:

SQLite uses 1 for true and 0 for false:

SQLite 没有单独的布尔存储类.相反,布尔值存储为整数 0(假)和 1(真).

SQLite does not have a separate Boolean storage class. Instead, Boolean values are stored as integers 0 (false) and 1 (true).

但 SQLite 也有一个松散的类型系统并自动转换,所以你的 'f' 可能被解释为具有true"的真实性,因为它不是零.

But SQLite also has a loose type system and automatically casts things so your 'f' is probably being interpreted as having a truthiness of "true" simply because it isn't zero.

一点点挖掘表明您在 Rails 3.0.7 SQLiteAdapter 中发现了一个错误.在 active_record/connection_adapters/abstract/quoting.rb 中,我们找到了这些:

A bit of digging indicates that you have found a bug in the Rails 3.0.7 SQLiteAdapter. In active_record/connection_adapters/abstract/quoting.rb, we find these:

def quoted_true
  "'t'"
end

def quoted_false
  "'f'"
end

因此,默认情况下,ActiveRecord 假定数据库理解布尔列的 't''f'.MySQL 适配器覆盖这些以与布尔列的 tinyint 实现一起工作:

So, by default, ActiveRecord assumes that the database understands 't' and 'f' for boolean columns. The MySQL adaptor overrides these to work with its tinyint implementation of boolean columns:

QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze

#...

def quoted_true
  QUOTED_TRUE
end

def quoted_false
  QUOTED_FALSE
end

但是 SQLite 适配器不提供自己的 quoted_truequoted_false 实现,因此它获得了不适用于 SQLite 布尔值的默认值.

But the SQLite adapter does not provide its own implementations of quoted_true or quoted_false so it gets the defaults which don't work with SQLite's booleans.

't''f' 布尔值在 PostgreSQL 中工作,所以也许每个人都在使用 PostgreSQL 和 Rails 3,或者他们只是没有注意到他们的查询是't 工作正常.

The 't' and 'f' booleans work in PostgreSQL so maybe everyone is using PostgreSQL with Rails 3 or they're just not noticing that their queries aren't working properly.

我对此感到有点惊讶,希望有人能指出我哪里出错了,您不可能是第一个在 SQLite 中使用带有 Rails 3 的布尔列的人.

I'm a little surprised by this and hopefully someone can point out where I've gone wrong, you can't be the first person to use a boolean column in SQLite with Rails 3.

尝试将 defquoted_true;'1';enddefquoted_false;'0';end 修补到 ActiveRecord::ConnectionAdapters::SQLiteAdapter(或临时手工编辑它们到 active_record/connection_adapters/sqlite_adapter.rb),看看你是否得到了合理的 SQL.

Try monkey patching def quoted_true;'1';end and def quoted_false;'0';end into ActiveRecord::ConnectionAdapters::SQLiteAdapter (or temporarily hand-edit them into active_record/connection_adapters/sqlite_adapter.rb) and see if you get sensible SQL.

这篇关于Rails 3 SQLite3 布尔假的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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