DBIC::Schema::Loader 使う時のリレーションとか


いきおいついでにもういっちょ。
DBIC::Schema::Loader 任せってわけにいかないのは言うまでもないので、なんとかしてやらなきゃなりませんね。
んで、最初から「convention over configuration」な設計ができてれば MoFedge::Data::DBIC::Schema のように半自動化することもできると思いますが、すでにそうでもない感じwになってしまってる場合の対応を考えてみました。


まあ、結局のところ「規約じゃなくて設定」になるわけなんですが。
とりあえず、こんな設定ファイルをYAMLで書いて、

artist:
    relationship:
        cds:
            - has_many
            - cd
            - artist_id
    utf8_columns:
        - name
cd:
    relationship:
        artist_id:
            - belongs_to
            - artist
        tracks:
            - has_many
            - track
            - cd_id
        liner_notes:
            - might_have
            - liner_notes
            - 
            - proxy
                - notes
                - writer
    utf8_columns:
        - title

で、こいつをこんなふうに読ませる。(ついでに UTF8Columns なんかも面倒見てます)

my $config  = YAML::Syck::LoadFile( $config_yaml );
my $classes = $schema->loader->classes;

for my $table_name ( keys %$config ) {
    my $class = $classes->{$table_name};

    my $relationship = $config->{$table_name}->{relationship};

    if ( ref $relationship eq 'HASH' ) {
        for my $accessor ( keys %{$relationship} ) {
            my ( $relation_type, $related_class_name, @attr )
                = @{ $relationship->{$accessor} };
            my $related_class =
                ( $relation_type ne 'many_to_many' )
                ? $classes->{$related_class_name}
                : $related_class_name;
            $class->$relation_type( $accessor => $related_class, @attr );
        }
    }

    my $utf8_columns = $config->{$table_name}->{utf8_columns};

    if ( ref $utf8_columns eq 'ARRAY' ) {
        $class->load_components(qw/UTF8Columns/);
        $class->utf8_columns( @{$utf8_columns} );
    }
}

とりあえずこれだけできればOKかなあ。あとなんかあるかしら。
他にもなんかおかしかったりしたら、どなたかつっこんでくださいませ。