Mik*_*ike 9 sqlite ruby-on-rails ruby-on-rails-3 rails-activerecord
我试图在SQLite3表中插入一个错误的布尔值,但它总是插入一个真值.
这是我的迁移:
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:
INSERT INTO "users" ("name", "active") VALUES ('test', 'f')
SQLite将'f'视为true,因此它将true插入到我的数据库中.我想要它生成的查询是:
INSERT INTO "users" ("name", "active") VALUES ('test', false)
我究竟做错了什么?
rails:3.0.7
sqlite3 gem:1.3.3
mu *_*ort 21
SQLite使用1表示true,0表示false表示:
SQLite没有单独的布尔存储类.相反,布尔值存储为整数0(假)和1(真).
但SQLite也有一个松散的类型系统并自动转换东西,因此你'f'可能被解释为具有"真实"的真实性,因为它不是零.
一点挖掘表明您在Rails 3.0.7 SQLiteAdapter中发现了一个错误.在active_record/connection_adapters/abstract/quoting.rb,我们发现这些:
def quoted_true
  "'t'"
end
def quoted_false
  "'f'"
end
因此,默认情况下,ActiveRecord假定数据库理解't'并且'f'对于布尔列.MySQL适配器会覆盖它们以使用其tinyint布尔列的实现:
QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
#...
def quoted_true
  QUOTED_TRUE
end
def quoted_false
  QUOTED_FALSE
end
但SQLite的适配器不提供自己的实现quoted_true或quoted_false因此它的不使用SQLite的布尔工作的默认值.
在't'和'f'PostgreSQL中布尔工作,所以也许每个人都使用PostgreSQL了Rails 3或者他们只是没有注意到,他们的查询工作不正常.
我对此感到有些惊讶,希望有人可以指出我出错的地方,你不能成为第一个在SQLite中使用Rails 3的布尔列的人.
尝试猴子修补def quoted_true;'1';end并def quoted_false;'0';end进入ActiveRecord::ConnectionAdapters::SQLiteAdapter(或暂时手动编辑它们active_record/connection_adapters/sqlite_adapter.rb),看看你是否得到合理的SQL.
| 归档时间: | 
 | 
| 查看次数: | 7954 次 | 
| 最近记录: |