【问题标题】:How to create a row object that contains related objects in DBIx::Class?如何在 DBIx::Class 中创建包含相关对象的行对象?
【发布时间】:2012-08-16 12:26:57
【问题描述】:

当你createDBIx::Class 中的 Row 对象时,你可以将相关对象作为值传递,例如

my $author = $authors_rs->find(1);
my $book = $books_rs->create({ author => $author, title => 'title' });

但是,如果您稍后使用author 访问器,则会再次从数据库中检索该对象。是否可以创建一个对象,以便无需额外查询即可访问关联的对象?

【问题讨论】:

  • 这是个好问题。您可能想在 DBIx::Class 邮件列表上询问它,开发人员常去的地方。在我看来,在创建之后将作者对象缓存在本书的范围内应该是可能的。但可能 DBIC 总是偏向于检索相关记录以确保新鲜度。

标签: perl relationship dbix-class


【解决方案1】:

将你想要的从 $author 复制到一些普通的旧 Perl 变量中怎么样?

如果您想复制整个结构,clone 模块可能会有所帮助(我没有使用此模块的经验;我只是在网上找到的)。

【讨论】:

    【解决方案2】:

    我不确定我是否正确理解了您,但如果我理解了,也许您想研究一下 prefetch 功能,以便自动准备好调用那些其他相关的行对象。

    例如在Galileo中,在列出所有页面(文章)时,我使用这种机制来获取每个页面对象(see here)的相关作者对象。


    好的,如果要在另一个对象中存储一个对象,您可能需要向对象中注入一些额外的数据。

    未经测试:

    ## some initial checks (run these only once)
    
    # check that method name is available
    die "Cannot use method 'extra_data'" if $book->can('extra_data');
    
    # check that the reftype is a hash
    require Scalar::Util;
    die "Incorrect underlying type" unless Scalar::Util::reftype($book) eq 'HASH';
    
    # check that the key is available
    die "Key unavailable" if exists $book->{'my_extra_data'};
    
    {
      no strict 'refs';
      # create a simple accessor for a hash stored in an object
      *{ ref($book) . '::extra_data' } = sub {
        my $self = shift;
    
        #return all extra data if called without args
        return $self->{my_extra_data} unless @_; 
    
        my $key = shift;
        if (@_) {
          $self->{my_extra_data}{$key} = shift;
        }
    
        return $self->{my_extra_data}{$key};
      };
    }
    
    $book->extra_data( author => $author );
    
    #then later
    
    my $stored_author = $book->extra_data('author');
    

    【讨论】:

    • prefetch 用于JOINs(即SELECTs),而我有一个不同的用例。我已经有一个相关的对象,并希望将其存储在新创建的对象(具有外键)中,这样就不需要再次检索它(在不同的文件/代码范围中)
    • 好的,所以你有一些代码可以将行对象返回到另一个范围(否则你需要另一个SELECT)。你不能只返回两个对象而不是一个吗?也许您想返回一个包含两者的集合“对象”?我的意思是,无论你通过什么渠道移动你的行对象,你都应该能够同时移动,我想。
    猜你喜欢
    • 1970-01-01
    • 2012-09-28
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多