【问题标题】:DBIx::Class insert has manyDBIx::Class 插入有很多
【发布时间】:2014-09-01 14:19:54
【问题描述】:

我正在使用DBIx::Class,我有两个架构:

use utf8;
package MyApp::Schema::Result::Person;

use Moose;
use MooseX::NonMoose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Core';

__PACKAGE__->table("person");

__PACKAGE__->add_columns(
    "id",
     { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
);

__PACKAGE__->has_many(
    "addresses",
    "MyApp::Schema::Result::Address",
    { "foreign.person_id" => "self.id" },
    { cascade_copy => 0, cascade_delete => 0 },
);

1;

还有:

use utf8;
package MyApp::Schema::Result::Address;

use Moose;
use MooseX::NonMoose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Core';

__PACKAGE__->table("address");

__PACKAGE__->add_columns(
    "id",
     { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
     "person_id",
     { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
);

__PACKAGE__->belongs_to(
    "person",
     "MyApp::Schema::Result::Person",
     { id => "person_id" },
     {  
         is_deferrable => 0,
         join_type     => "LEFT",
         on_delete     => "NO ACTION",
         on_update     => "NO ACTION",
     },  
);

1;

我想要做的是用一个人对象一次添加多个地址。我就是这样做的:

my $person = $c->model('DB::Person')->new_result({});
$person->addresses([
    {
        id => 1,
        person_id => 1,
    },
    {
        id => 2,
        person_id => 1,
    },
]);

$person->insert;

我从article 遵循了这种格式,但它似乎不起作用。仅插入人员行,但不插入与其关联的地址。我还尝试在插入之前将addresses 设置为MyApp::Schema::Result::Address 对象的arrayref,但这也不起作用。有谁知道我做错了什么?我没有收到任何错误,只是没有插入地址。在文章中,他们使用 create 而不是 insert。是不是因为这个?如果是这样,有没有办法使用insertupdate 来做到这一点?

【问题讨论】:

    标签: perl catalyst dbix-class


    【解决方案1】:

    当您添加相关的子记录时,您不需要为子记录指定外键的值。这段关系应该会自动为您解决这个问题。例如在您的示例中 person_id 是不必要的。

    我怀疑这可能会导致示例中出现问题。你怎么知道 person_id 真的是 1?它是一个自动增量列,您在创建 Person 时没有显式传递值。

    这会发生什么:

    -- 在 Person.pm 中--

    __PACKAGE__->add_columns(
        "id",
         { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
        "name",
         { data_type => "varchar"},
    );
    

    -- 在地址.pm中--

    __PACKAGE__->add_columns(
        "id",
         { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
         "person_id",
         { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
        "street",
         { data_type => "varchar"},
    

    );

    然后这个插入代码:

    my $person = $c->model('DB::Person')->new_result({ name => "Bob" });
    $person->addresses([
        {
            street => "Apple Street",
        },
        {
            street => "Orange Avenue",
        },
    ]);
    
    $person->insert;
    

    【讨论】:

      【解决方案2】:

      我原以为你在Address 中的belongs_to 关系应该是这样的

      { 'foreign.id' => 'self.person_id' }
      

      因为id 在没有指定表名的情况下是不明确的。

      您的Person 似乎在has_many 关系中具有正确性

      【讨论】:

      • 嗯,是的,这很奇怪。这些定义是由 DBIx::Class::Schema::Loader 刚刚为我创建的。他们似乎工作正常。
      【解决方案3】:

      我很确定这与仅在内存中创建的 Person 对象有关,请尝试改用 create。

      在分配地址后,您是否有理由要插入它?

      请注意,您在一个 DBIx::Class::Schema 中有两个 DBIx::Class::Result 类。

      您也不应该覆盖自动增量列值,因为您的数据库不会知道这些 ID 已被使用,并且稍后尝试这样做会导致难以追踪的错误。

      【讨论】:

      • 分配地址后我想插入它的原因是因为我首先使用 HTML::FormHandler 来验证它,而 HTML::FormHandler 需要一个项目来验证表单,所以我有在我打那个电话之前有排。另外,我实际上并没有分配自动增量 ID——这只是一个例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      相关资源
      最近更新 更多