При использовании DBIx :: Class Schema Loader, есть ли способ поддерживать пользовательские отношения и методы в отдельных файлах? - PullRequest
2 голосов
/ 25 июля 2010

В настоящее время мы используем DBIx :: Class :: Schema :: Loader для генерации и регенерации (при изменении нашей схемы БД) набора классов Result.

Мы добавляем дополнительные отношения и методы в конец этих классов, и это вызывает ад слияния, когда люди регенерируют или изменяют схему.

Мы хотели бы сохранить наши пользовательские изменения в отдельном наборе файлов, которые располагаются параллельно с автоматически сгенерированными.

Есть ли простой, чистый, рекомендуемый способ сделать это?

Ответы [ 3 ]

0 голосов
/ 04 октября 2010

Я решил это путем Moosification схем и создания набора Moose :: Roles, которые я применяю к классам Schema сразу после schema-> connection ();

Это выглядит примерно так:

my $schema = My::Schema->connection();

foreach my $source ($schema->sources) {

    my $domain_pkg = "My::Domain::$source";

    eval  "require $domain_pkg";

    # ignore failures due to file-not-found
    if ($@ && $@ =~/^Can't locate.*INC/) {

    # but barf if class doesnt compile
    } elsif ($@) {
        confess "Failed to load $domain_pkg for $pkg!!: - $@";

    # re-register domain class with the resultsource
    # and apply the role 
    } else {
        my $schema_pkg = "${pkg}::$source";
        $c->register_class($source, $schema_pkg);

        use Moose::Util;
        # check schema is moosyfied
        if ( $schema_pkg->can('meta') ) {
            my $meta = $schema_pkg->meta;

            eval {
                Moose::Util::apply_all_roles($meta, $domain_pkg);
            };
            if ($@) {
                confess "Failed to add $domain_pkg role to $schema_pkg: $@\n";
            } else {
                l4p->info("Found and applied Domain role: '$domain_pkg' for schema: '$schema_pkg'");
            }

        } else {
            warn "Cant call meta on $schema_pkg. ";
        }

    }

}

Рядом ..

use MooseX::Declare 

role My::Domain::Person {

    # modify schema
    My::Schema::Person->inflate_column( ..);
    My::Schema::Person->belongs_to(..);
    My::Schema::Person->set_primary_key(..);

    # add some method modifiers to check/modify construction 
    around new (ClassName $class : $params) {

        munge params..

        $self->$orig($params);
    }

    # post insert hook
    after insert () {
        do_something..
    }

    # domain methods
    sub fullname {
         $self->firstname.' '.$self->surname;
    }



}
0 голосов
/ 15 августа 2014

Хотя технически это не ответ на вопрос, это решение проблемы ада слияния, которая его породила. При вызове dbicdump или make_schema_at вы можете установить флаги omit_version и omit_timestamp, которые будут генерировать подпись, как показано ниже:

# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CKsL4EO4b/JE3QXBSC4EXg

При повторном сбросе эта подпись не должна изменяться, если только не изменяются фактические таблицы, поэтому любой элемент управления версиями не увидит необоснованных конфликтов.

0 голосов
/ 02 октября 2010

Я столкнулся с той же проблемой. Вы можете просто создать другой класс, который наследует от сгенерированных классов. Тем не менее, вам нужно перетащить ссылку на таблицу и отношения в класс, который вы редактируете, но вы можете оставить определения столбцов и того, что не в сгенерированном классе. Я в основном написал помощник для загрузчика, который генерирует классы в пространство имен «Immutable» и создает дочерний элемент для каждого из них в пространстве имен «Mutable» вместе со ссылкой на имя таблицы и отношениями сгенерированной модели. Кажется, он работает достаточно хорошо, и мне больше не нужно беспокоиться о том, что разработчики редактируют сгенерированный раздел класса. Я, наверное, должен написать все это в блоге на днях.

...