目前我們使用DBIx::Class::Schema::Loader生成和重新生成(當我們的數據庫模式更改時)一組Result類。當使用DBIx :: Class Schema Loader時,有沒有辦法在單獨的文件中維護自定義關係和方法?
我們將其他關係和方法添加到這些類的底部,當人們重新生成或更改模式時,這會導致合併地獄。
我們希望將我們的自定義更改保留在與自動生成的文件並行的單獨文件集中。
有沒有一個簡單,乾淨,推薦的方法呢?
目前我們使用DBIx::Class::Schema::Loader生成和重新生成(當我們的數據庫模式更改時)一組Result類。當使用DBIx :: Class Schema Loader時,有沒有辦法在單獨的文件中維護自定義關係和方法?
我們將其他關係和方法添加到這些類的底部,當人們重新生成或更改模式時,這會導致合併地獄。
我們希望將我們的自定義更改保留在與自動生成的文件並行的單獨文件集中。
有沒有一個簡單,乾淨,推薦的方法呢?
我遇到了同樣的問題。您可以創建另一個從生成的類繼承的類。但是,您需要將表引用以及關係轉換爲正在編輯的類,但是可以保留列定義以及不在生成的類中的內容。我基本上爲加載器編寫了一個助手,它將類生成爲「不可變」命名空間,並在「可變」命名空間中爲它們中的每一個創建子對象,以及表名引用和生成模型中的關係。它看起來工作得很好,而且我不再擔心開發人員正在編輯該類的生成部分。我應該在這些日子的博客文章中寫下整件事。
聽起來像你在正確的線:) – Tom 2010-10-04 13:23:10
我解決了這個問題,方法是先模式化,然後創建一組Moose :: Roles,這些Moose :: Roles適用於schema-> connection()之後的Schema類。
它去有點像這樣:
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 ([email protected] && [email protected] =~/^Can't locate.*INC/) {
# but barf if class doesnt compile
} elsif ([email protected]) {
confess "Failed to load $domain_pkg for $pkg!!: - [email protected]";
# 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 ([email protected]) {
confess "Failed to add $domain_pkg role to $schema_pkg: [email protected]\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;
}
}
雖然這不是技術上的問題的答案,這是合併地獄問題的解決方案催生了它。當調用dbicdump
或make_schema_at
,你可以設置omit_version
和omit_timestamp
標誌,這將產生一個簽名如下圖所示:
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CKsL4EO4b/JE3QXBSC4EXg
當重新傾銷,此簽名不應該改變,除非實際表做的,所以任何版本控制不會看到不合理的衝突。
請問您能解釋一下目前導致合併地獄的事情嗎?從理論上講,自動生成的和用戶創建的部分明顯是分開的,因爲第一個部分是校驗和,第二個部分不是,這應該很容易合併。這裏有什麼確切的問題?你能提供一個例子嗎? – Jonas 2010-07-25 07:01:06
如果2個人進行模式更改並在獨立的分支中重新生成Schema文件,他們將在Schema類的上半部分中創建衝突,這幾乎不會導致校驗和不正確。 – Tom 2010-07-31 14:29:12