Rails无法识别旧数据库中的布尔字段

时间:2012-07-26 11:17:17

标签: mysql ruby-on-rails activerecord database-migration

我编写了一个使用遗留MySQL数据库的Rails应用程序。一个表包含此字段

CREATE TABLE `articles` (
  `active` tinyint(3) unsigned NOT NULL DEFAULT '0',
);

我用

修复了架构
t.boolean "active",    :default => false

但是rails不会将该字段识别为boolean

[1] pry(main)> Article.new.active.class
=> Fixnum

这会在验证时产生问题,因为我在班级中有这个验证器

class Article < ActiveRecord::Base
  validates_inclusion_of :active, :in => [true, false]
end

当我为该字段分配布尔值时,它们将转换为FixNum,验证失败并显示消息"1 is not included in the list"

如果我使用相同型号生成新应用程序,则生成的sql代码为

CREATE TABLE `posts` (
  `active` tinyint(1) DEFAULT NULL,
)

一切正常:

[1] pry(main)> Article.new.active.class
=> FalseClass

有没有办法让我的遗留列被识别为布尔值(可能没有运行迁移)?

2 个答案:

答案 0 :(得分:0)

TrueClassFalseClass中的overriding方法,如果只是定义您自己的“遗留”布尔值以供验证使用,可以接受这些方法:< / p>

class Article < ActiveRecord::Base
  $legacy_false, $legacy_true = 0, 1
  validates_inclusion_of :active, :in => [$legacy_true, $legacy_false]
end

答案 1 :(得分:0)

好的,我found out对于MySQL布尔类型硬编码为tinyint(1)

def simplified_type(field_type)
  return :boolean if adapter.emulate_booleans && field_type.downcase.index("tinyint(1)")

  case field_type
    when /enum/i, /set/i then :string
    when /year/i         then :integer
    when /bit/i          then :binary
  else
    super
  end
end

我在我的数据库上运行此迁移以使其正常工作

class ChangeBooleanFields < ActiveRecord::Migration
  def up
    change_column :articles, :active, :boolean, :null => false, :default => false, :limit => nil
  end

  def down
    change_column :articles, :active, :integer, :null => false, :default => 0, :limit => 1
  end
end