元フリーエンジニアライフ

Ruby on Rails とか MovableType とかAWSやってるフリーランスウェブエンジニアの記録でした。現在は法人成りしてIT社長。

MTプラグインで拡張したカラムにインデックスを貼ったりデフォルト値を設定したりするには

MTプラグインを作成する際、既存のオブジェクト(記事 MT::Entry とか)に、プラグイン独自の属性を追加する場合がある。

このとき、config.yamlでこんな風にするのが基本。

object_types:
    entry:
        myid: integer

追加したカラムにインデックスを貼ったり、デフォルト値を設定したりしたくなったら・・・?

MT::Object的には

__PACKAGE__->install_properties ( {
    column_defs => {
        myid: 'integer'
    },
    indexes => {
        myid => 1,
    },
    defaults => {
        myid => 0,
    },

こんな感じのことだ。

lib/MT/Object.pm を読んでみると

# check for any supplemental columns from other components
my $more_props = MT->registry( 'object_types', $type_id );
if ( $more_props && ( ref($more_props) eq 'ARRAY' ) ) {
    my $cols = {};
    for my $prop (@$more_props) {
        next if ref($prop) ne 'HASH';
        MT::__merge_hash( $cols, $prop, 1 );
    }
    my @classes = grep { !ref($_) } @$more_props;
    foreach my $isa_class (@classes) {
        next if UNIVERSAL::isa( $class, $isa_class );
        eval "# line " 
            . __LINE__ . " " 
            . __FILE__
            . "\nno warnings 'all';require $isa_class;"
            or die;
        no strict 'refs';    ## no critic
        push @{ $class . '::ISA' }, $isa_class;
    }
    if (%$cols) {

        # special case for 'plugin' key...
        delete $cols->{plugin} if exists $cols->{plugin};
        for my $name ( keys %$cols ) {
            next if exists $props->{column_defs}{$name};
            if ( $cols->{$name} =~ m/\bmeta\b/ ) {
                $meta{$name} = $cols->{$name};
                next;
            }

            $class->install_column( $name, $cols->{$name} );
            $props->{indexes}{$name} = 1
                if $cols->{$name} =~ m/\bindexed\b/;
            if ( $cols->{$name} =~ m/\bdefault (?:'([^']+?)'|(\d+))\b/ ) {
                $props->{defaults}{$name} = defined $1 ? $1 : $2;
            }
        }
    }
}

ということで、レジストリに設定する文字列に「indexed」「default」を追加するだけで良いようだ。

object_types:
    entry:
        myid: integer indexed default 0

※not null制約を付けるなら「integer not null indexed default 0」