2

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

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

我已经修复了架构

t.boolean "active",    :default => false

但是 rails 不会将该字段识别为布尔值

[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

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

4

2 回答 2

0

在and中缺少覆盖方法,是否可以按照以下方式简单地定义您自己的“旧”布尔值以用于您的验证:TrueClassFalseClass

class Article < ActiveRecord::Base
  $legacy_false, $legacy_true = 0, 1
  validates_inclusion_of :active, :in => [$legacy_true, $legacy_false]
end
于 2012-07-26T12:09:26.690 回答
0

好的,我发现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
于 2012-07-26T14:09:32.093 回答