タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

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」