2014-07-11 3 views
3

J'utilise DBIx::Class et j'ai deux schemas:DBIx :: insert de classe a beaucoup

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; 

Et:

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; 

Ce que je suis en train de faire est d'ajouter plusieurs adresses à la fois avec un objet personne. Je fais cela comme ceci:

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

$person->insert; 

J'ai suivi ce format de cette article, mais il ne semble pas fonctionner. Seule la ligne de personne est insérée, mais pas les adresses associées. J'ai également essayé de placer addresses à un arrayref d'objets MyApp::Schema::Result::Address avant l'insertion, mais cela ne fonctionne pas non plus. Est-ce que quelqu'un sait ce que je fais mal? Je ne reçois aucune erreur, il n'insère pas les adresses. Dans l'article, ils utilisent create au lieu d'insert. Est-ce à cause de ça? Si oui, existe-t-il un moyen de le faire en utilisant insert ou update?

Répondre

0

Je suis assez sûr que cela a à voir avec l'objet Person créé uniquement en mémoire, essayez plutôt d'utiliser create.

Y a-t-il une raison pour laquelle vous voulez l'insérer après avoir attribué les adresses?

Notez que vous avez deux classes DBIx :: Class :: Result dans un DBIx :: Class :: Schema.

Vous ne devez pas non plus ignorer les valeurs de colonnes à incrémentation automatique car votre base de données ne sait pas que ces identifiants sont déjà utilisés et tente de le faire plus tard, ce qui entraîne une erreur de traçage.

+0

La raison pour laquelle je veux insérer après avoir attribué les adresses est parce que je suis d'abord en utilisant HTML :: FormHandler pour le valider, et HTML :: FormHandler a besoin d'un élément à valider le formulaire, donc je dois avoir la ligne avant de faire cet appel. De plus, je n'attribue pas les identifiants d'incrémentation automatique - c'était juste par exemple. – srchulo

1

J'aurais pensé que votre relation belongs_to dans Address devrait ressembler à

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

parce id est ambigu sans spécifier un nom de table.

Vous semblez avoir plein pour votre Person

relation has_many
+0

Hmm, ouais c'est étrange. Les définitions viennent d'être créées par DBIx :: Class :: Schema :: Loader. Ils semblent bien fonctionner. – srchulo

2

Lorsque vous ajoutez des enregistrements enfants connexes que vous ne avez pas besoin de spécifier la valeur de la clé étrangère pour les enfants. La relation devrait prendre soin de cela pour vous automatiquement. par exemple. dans votre exemple, person_id est inutile. Je suppose que cela peut causer un problème dans l'exemple. Comment savez-vous que le person_id est vraiment 1? C'est une colonne auto-incrémentée, et vous ne passez pas explicitement une valeur lorsque vous créez la Personne.

Qu'est-ce qui se passe avec ceci:

- Dans Person.pm -

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

- Dans le champ Adresse.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"}, 

);

Ensuite, ce code d'insertion:

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

$person->insert; 
Questions connexes