【问题标题】:How to setup a DBIx::Class schema with Moose -- the definite guide如何使用 Moose 设置 DBIx::Class 模式——明确指南
【发布时间】:2014-04-24 08:34:07
【问题描述】:

我发现很难找到有关如何使用Moose 组装DBIx::Class 模式结构的信息。如何在现代 Perl 中正确地做到这一点(基本上可以工作)(良好的风格、快速、没有警告)?

这些是我的目标:

  • 关注 Moose'Moose::Manual::BestPractices,特别是:
    • 使用namespace::autoclean
    • 使用__PACKAGE__->meta->make_immutable
  • 使用ResultResultSet 的通用基类
  • 当使用任何魔术时,请在评论中解释它们(在研究过程中,我发现了一个建议 sub BUILDARGS { $_[2] }don't ask 解释的指南)
  • 移动通用代码,例如MooseX::NonMoose(如有必要)或__PACKAGE__->load_components,按照DBIx::Class::Manual::Cookbook 的建议进入公共基类

这些是我遇到的问题:

  • 当使用__PACKAGE__->meta->make_immutable 时,我收到了类似Not inlining 'new' for MyApp::Schema::Result::MyTable since it is not inheriting the default Moose::Object::new 的警告
  • 将所有对 __PACKAGE__->load_components 的调用移动到 Result 基类时,我的 datetime 列没有膨胀

【问题讨论】:

    标签: perl moose dbix-class


    【解决方案1】:

    出现的问题的解决方案:

    • make_immutable 与非Moose new 构造函数冲突:这由use MooseX::NonMoose 自动处理;与其文档相比,不需要进一步的论据或选项;请注意 DBIx::Class::Schema 没有 new 方法,因此,MyApp::Schema 不需要需要这个帮助器
    • InflateColumn::DateTime 在基类中加载时不会膨胀:这是由赋予load_components() 的组件顺序触发的;文档中没有暗示顺序应该很重要,我已经为此提交了a bug report;重新排序有帮助

    上面的解决方案包括我的示例 DBIx::Class 模式与 Moose 看起来像这样:

    架构类:

    package MyApp::Schema;
    
    use Moose; # we want Moose
    use MooseX::MarkAsMethods autoclean => 1; # this helps removing unused symbols like Moose keywords
    # do NOT 'use MooseX::NonMoose' here because Schema class has no 'new' method
    
    extends 'DBIx::Class::Schema'; # the Moose way of inheritance
    
    # load all table modules automatically
    __PACKAGE__->load_namespaces(
        # ResultSet class for tables without custom ResultSet class
        # (would be DBIx::Class::ResultSet otherwise)
        default_resultset_class => '+MyApp::Schema::ResultSet',
    );
    
    # tell Moose this class is finished: some Moose stuff is removed and things go faster
    __PACKAGE__->meta->make_immutable;
    
    1;
    

    通用Result基类:

    # a base class for all table class of this app
    package MyApp::Schema::Result;
    
    use Moose;
    use MooseX::MarkAsMethods autoclean => 1;
    use MooseX::NonMoose; # this is important for correctly handling DBIx::Class' new
    
    extends 'DBIx::Class::Core';
    
    # this is the right place to implement generic stuff
    
    # DBIx::Class::Cookbook recommends loading components in a central place
    __PACKAGE__->load_components(qw/
        InflateColumn::DateTime
        ...
    /);
    
    __PACKAGE__->meta->make_immutable;
    
    1;
    

    通用ResultSet基类:

    package MyApp::Schema::ResultSet;
    
    use Moose;
    use MooseX::MarkAsMethods autoclean => 1;
    use MooseX::NonMoose;
    
    extends 'DBIx::Class::ResultSet';
    
    __PACKAGE__->meta->make_immutable;
    
    1;
    

    ResultSet 表类my_table 的示例:

    package MyApp::Schema::ResultSet::MyTable;
    
    use Moose;
    use MooseX::MarkAsMethods autoclean => 1;
    
    extends 'MyApp::Schema::ResultSet';
    
    sub oldest {
        my $self = shift;
    
        $self->search({}, {order_by => {-ASC => 'date'}})->first;
    }
    
    __PACKAGE__->meta->make_immutable;
    
    1;
    

    Result 表类my_table 的示例:

    package MyApp::Schema::Result::MyTable;
    
    use Moose;
    use MooseX::MarkAsMethods autoclean => 1;
    
    extends 'MyApp::Schema::Result';
    
    __PACKAGE__->table("my_table");
    
    __PACKAGE__->add_columns(
        id   => {data_type => "integer", is_auto_increment => 1},
        date => {data_type => "date"},
    );
    
    __PACKAGE__->set_primary_key("id");
    
    __PACKAGE__->meta->make_immutable;
    
    1;
    

    【讨论】:

    • 使用严格;并使用警告;使用 Moose 自动启用,不是必需的。我使用 namespace::autoclean 而不是 MooseX::MarkAsMethods 这对我来说也很好。
    • 感谢您指出这一点。我今天阅读了大量文档,但现在找不到推荐 MooseX::MarkAsMethods 而不是 namespace::autoclean 的确切位置。您认为有充分的理由坚持两者中的任何一个吗?
    • 感谢您的指导,我喜欢这个。 stackoverflow.com/questions/7734892/… 地址 namespace::autoclean 和 MooseX::MarkAsMethods。
    • @Oesor 谢谢你的链接。根据其中一个答案,MooseX::MarkAsMethods 的发明是为了解决namespace::autoclean 的一些问题,以及Moose 的高级(不是说奇怪)使用。因此,保持这种状态似乎是最安全的方法。
    【解决方案2】:

    DBIx::Class::Schema::Loader 中使用use_moose 有什么问题? (例如dbicdump -o use_moose=1 MyApp::Schema <dsn> <user> <pass>

    这是use_moose=1 in DBIx::Class::Schema::Loader 0.07039 为架构生成的内容:

    use utf8;
    package MyApp::Schema;
    
    # Created by DBIx::Class::Schema::Loader
    # DO NOT MODIFY THE FIRST PART OF THIS FILE
    
    use Moose;
    use MooseX::MarkAsMethods autoclean => 1;
    extends 'DBIx::Class::Schema';
    
    __PACKAGE__->load_namespaces;
    
    
    # Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-03-19 22:50:18
    # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7Hx1RMeFsxCqo5YaLOzPdQ
    
    
    # You can replace this text with custom code or comments, and it will be preserved on regeneration
    __PACKAGE__->meta->make_immutable(inline_constructor => 0);
    1;
    

    结果类:

    use utf8;
    package MyApp::Schema::Result::Example;
    
    # Created by DBIx::Class::Schema::Loader
    # DO NOT MODIFY THE FIRST PART OF THIS FILE
    
    use strict;
    use warnings;
    
    use Moose;
    use MooseX::NonMoose;
    use MooseX::MarkAsMethods autoclean => 1;
    extends 'DBIx::Class::Core';
    
    ...yadda...
    
    
    # Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-03-19 22:50:18
    # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yTmu6Rh9TAEwxqgDClBdtg
    
    
    # You can replace this text with custom code or comments, and it will be preserved on regeneration
    __PACKAGE__->meta->make_immutable;
    1;
    

    这是creating a Moosified ResultSet class的文档

    看起来它确实有一些无关紧要的 use strictuse warnings 但没什么大不了的。 好消息是,如果有任何变化,希望 DBIx::Class::Schema::Loader 能够更新以适应任何需要的变化。

    抱歉,如果我没有抓住重点。

    【讨论】:

    • 感谢您指出这一点。我已经开始通过编写Result 类来开发数据库表,并使用模式部署数据库。我本可以检查加载器为我部署的模式生成的内容,但我仍然发现首先拥有一个用于编写漂亮模式的模板很有用。我还发现了不同手册之间的一些差异,并开始社区 wiki 文章以给出明确的答案。
    • 这应该被选为正确答案。它是 dbicdump(DBIx::Class::Schema::Loader 的一部分)的官方记录和支持的方法,用于创建 Moose 兼容的 DBIx::Class 文件...参见metacpan.org/pod/DBIx::Class::Schema::Loader::Base#use_moose
    猜你喜欢
    • 2013-09-04
    • 2011-01-24
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2014-12-16
    相关资源
    最近更新 更多