2

レガシー MySQL データベースを使用する Rails アプリケーションを作成しました。1 つのテーブルにこのフィールドが含まれています

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

私はスキーマを修正しました

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

しかし、レールはそのフィールドをブール値として認識しません

[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 に答える