perl 形成正确的DBIx::Class语法,以连接一个表,在该表中,外键存储在另一个表的一对一连接中

wfsdck30  于 2023-11-22  发布在  Perl
关注(0)|答案(1)|浏览(203)

我一直在阅读文档并尝试一些东西,但我似乎无法想出创建关系所需的语法。我在这里简化了我的需求:

Table: thing  
Field: thingID  
Field: sprocketID  
Field: thingWidth  
(there are more fields)  

Table: sprocket  
Field: sprocketID  
Field: sprocketLength  
(there are more fields)  

Table: cog  
Field: sprocketLength  
Field: thingWidth  
Field: cogPartNum

字符串
我在试着做模型。

  • 每个事物都有一个链轮。多个事物可以有相同的链轮,这就是为什么我想在链轮表中存储链轮长度(以及有关链轮的其他信息),而不是在事物表中重复。多个链轮可以具有相同的长度。
  • 每个事物都有一个齿轮--您需要链轮的链轮长度和事物的事物宽度来确定哪个齿轮(以及哪个齿轮部件)。

下面的SQL为我提供了我要查找的值:

SELECT * FROM thing
    JOIN sprocket ON thing.sprocketID = sprocket.sprocketID
    JOIN cog ON sprocket.sprocketLength = cog.sprocketLength AND thing.thingWidth = cog.thingWidth
    WHERE thing.thingID = ?;


我有一些代码看起来像这样,但我不确定如何正确定义我的cond(齿轮关系定义上的第三个参数):

My::Schema::Thing->has_one('sprocket' => 'My::Schema::Sprocket', 'sprocketID');
My::Schema::Thing->has_one('cog' => 'My::Schema::Cog', {
    'foreign.thingWidth' => 'self.thingWidth',
    'foreign.sprocketLength' => *??????       # this is where I'm getting confused because sprocketLength isn't in self*
});


所以我想我可能需要为cond使用一个coderef定义,但是我很难让它工作。我得到了一些看起来像这样的东西:

My::Schema::Thing->has_one('cog' => 'My::Schema::Cog', sub {
    my $args = shift;
    return {
        "$args->{foreign_alias}.thingWidth" => { -ident => "$args->{self_alias}.thingWidth" },
        "$args->{foreign_alias}.sprocketLength" => $self->{self_result_object}->sprocket->sprocketLength,
    };
});


但这似乎对我不起作用。我试图调用$self->cog-> cogPartition来访问我的主代码中的一个东西的cogPartition。我经历了多次执行coderef(确切地说是3次),最后一次没有定义$self->{self_result_object},所以我在尝试访问undef的sprocket方法时出错。
更新:通过使用DBIx::Class::Relationship::Base的perldoc中的一些代码示例,我已经接近了一点,尽管我仍然没有完全理解它。返回中的第二个值与“join-free”情况有关。这似乎可以工作,但是如果我想使用join case(第一个返回值)来预取我的值,下面的代码仍然失败。

sub {
    my $args = shift;
 
    return (
        {
            "$args->{foreign_alias}.thingWidth" => { -ident => "$args->{self_alias}.thingWidth" },
            "$args->{foreign_alias}.sprocketLength" => $self->{self_result_object}->sprocket->sprocketLength,   # this is why it fails
        },
        ! $args->{self_result_object} ? () : {
            "$args->{foreign_alias}.thingWidth" => $args->{self_result_object}->thingWidth,
            "$args->{foreign_alias}.sprocketLength" => $args->{self_result_object}->sprocketLength,
        },
        (),
    );
}


你有什么指导吗?请原谅任何错别字,因为我只是从记忆中打出来的。

zf2sa74q

zf2sa74q1#

您的sprocketcog关系应该是belongs_to

__PACKAGE__->belongs_to('sprocket' => 'My::Schema::Sprocket', 'sprocketID');

字符串
要使它工作,你需要有链轮关系加入。DBIC不提供一种方法来添加一个连接时,关系涉及到据我所知。
你在正确的轨道上使用-ident,基本上它所做的就是将其值传递给生成的SQL,所以如果你确保链轮关系被连接,这样的事情应该可以工作:

__PACKAGE__->belongs_to('cog' => 'My::Schema::Cog', sub {
    my $args = shift;
    return {
        "$args->{foreign_alias}.thingWidth" => { -ident => "$args->{self_alias}.thingWidth" },
        "$args->{foreign_alias}.sprocketLength" => { -ident => "sprocket.sprocketLength" },
    };
});


在ResultSet和/或Result类上有一个方法来做这件事是我的首选方法。我给所有返回ResultSet或Result对象数组的方法加上前缀search_

相关问题