Rails2.3.14+MySQL5.1でテーブル&カラムコメントをMigrationで追加する

以前書いたエントリPostgresqlでのコメントを追加したが、Rails2.3.14案件でテーブル&カラムコメントをつける必要が出たのでメモ。

※2012/6/20 add_column_commentメソッドを一部修正

パッチ

これをconfig/initializers/column_comment.rbにでも入れておけば、Migration時にコメントを付加してくれる。

注意点
Rails2.3.14のMigration部分を思い切りコピペして改造しているため、意図しない動きになるかもしれない。

# NOTICE : Rails2.3.14のActiveRecordを前提としている。
module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter
      def create_table(table_name, options = {})
        table_definition = TableDefinition.new(self)
        table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false

        yield table_definition if block_given?

        if options[:force] && table_exists?(table_name)
          drop_table(table_name, options)
        end

        create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
        create_sql << "#{quote_table_name(table_name)} ("
        create_sql << table_definition.to_sql
        create_sql << ") #{options[:options]}"
        if options[:comment]
          create_sql << " COMMENT '#{options[:comment]}'"
        end
        execute create_sql
      end

      def add_column(table_name, column_name, type, options = {})
        add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
        add_column_options!(add_column_sql, options)
        if comment = options[:comment]
          add_column_sql = "#{add_column_sql} COMMENT '#{comment}'"
        end
        add_column_position!(add_column_sql, options)
        execute(add_column_sql)
      end

      def add_column_comment(table_name, column_name, comment = "")
        options = {}
        if column = columns(table_name).find { |c| c.name == column_name.to_s }
          options[:default] = column.default
          options[:null] = column.null
        else
          raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
        end
        define = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")
        current_type = define["Type"]
        current_extra = define["Extra"]
        add_comment_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} COMMENT '#{comment}'"
        add_column_options!(add_comment_sql, options)
        add_comment_sql += " #{current_extra}" if current_extra.present?
        execute(add_comment_sql)
      end


      def add_table_comment(table_name, comment = "")
        add_comment_sql = "ALTER TABLE #{quote_table_name(table_name)} COMMENT '#{comment}'"
        execute(add_comment_sql)
      end

    end

    class ColumnDefinition
      attr_accessor :comment
      alias :_orig_to_sql :to_sql
      def to_commented_sql
        self.comment ? "#{_orig_to_sql} COMMENT '#{self.comment}'" : _orig_to_sql
      end
      alias to_sql :to_commented_sql
    end

    class TableDefinition
      alias :_orig_column :column
      def column(name, type, options = {})
        _orig_column(name, type, options)
        if comment = options[:comment]
          column = @columns.find { |col| col.name == name }
          pos = @columns.index(column)
          @columns[pos].comment = comment
        end
        self
      end
    end
  end
end

migrationファイルの書き方

以下の通り:commentオプション or 引数にで対応。

●テーブル作成時
    create_table :hoge_masters, :comment => "hogehoge" do |t|
      t.string   :code, :comment => "fugafuga"
    end
●カラム追加時
    add_column    :hoge_masters, :value, :integer, :comment => "コメコメ"
●テーブルコメント追加 ※独自作成機能
    add_table_comment    :hoge_masters, "テステス"
●カラムコメント追加   ※独自作成機能
    add_column_comment   :hoge_masters, :effective_value, "コメコメ111"