be turned into objects via new_related, and treated as if you had
passed objects.
+For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
+
=cut
## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
my $rel_obj = delete $attrs->{$key};
if(!Scalar::Util::blessed($rel_obj)) {
$rel_obj = $new->find_or_new_related($key, $rel_obj);
- $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
}
+
+ $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+
$new->set_from_related($key, $rel_obj);
$related->{$key} = $rel_obj;
next;
$rel_obj = $new->new_related($key, $rel_obj);
$new->{_rel_in_storage} = 0;
}
+
+ $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
}
$related->{$key} = $others;
next;
next;
}
}
- use Data::Dumper;
$new->throw_exception("No such column $key on $class")
unless $class->has_column($key);
$new->store_column($key => $attrs->{$key});
an entirely new object into the database, use C<create> (see
L<DBIx::Class::ResultSet/create>).
+This will also insert any uninserted, related objects held inside this
+one, see L<DBIx::Class::ResultSet/create> for more details.
+
=cut
sub insert {
foreach my $p (@pri) {
if (exists $keyhash->{$p}) {
- warn $keyhash->{$p};
unless (defined($rel_obj->get_column($keyhash->{$p}))
|| $rel_obj->column_info($keyhash->{$p})
->{is_auto_increment}) {
my $reverse = $source->reverse_relationship_info($relname);
foreach my $obj (@cands) {
$obj->set_from_related($_, $self) for keys %$reverse;
- $obj->insert() if(!$obj->in_storage);
+ $obj->insert() unless ($obj->in_storage || $obj->result_source->resultset->search({$obj->get_columns})->count);
}
}
}
$obj->in_storage; # Get value
$obj->in_storage(1); # Set value
-Indicated whether the object exists as a row in the database or not
+Indicates whether the object exists as a row in the database or not
=cut
reinserted using C<< ->insert() >> before C<< ->update() >> can be used
on it. If you delete an object in a class with a C<has_many>
relationship, all the related objects will be deleted as well. To turn
-this behavior off, pass C<cascade_delete => 0> in the C<$attr>
+this behavior off, pass C<< cascade_delete => 0 >> in the C<$attr>
hashref. Any database-level cascade or restrict will take precedence
over a DBIx-Class-based cascading delete. See also L<DBIx::Class::ResultSet/delete>.
$new->result_source($self->result_source);
$new->set_columns($changes);
$new->insert;
+
+ # Its possible we'll have 2 relations to the same Source. We need to make
+ # sure we don't try to insert the same row twice esle we'll violate unique
+ # constraints
+ my $rels_copied = {};
+
foreach my $rel ($self->result_source->relationships) {
my $rel_info = $self->result_source->relationship_info($rel);
- if ($rel_info->{attrs}{cascade_copy}) {
- my $resolved = $self->result_source->resolve_condition(
- $rel_info->{cond}, $rel, $new);
- foreach my $related ($self->search_related($rel)) {
- $related->copy($resolved);
- }
+
+ next unless $rel_info->{attrs}{cascade_copy};
+
+ my $resolved = $self->result_source->resolve_condition(
+ $rel_info->{cond}, $rel, $new
+ );
+
+ my $copied = $rels_copied->{ $rel_info->{source} } ||= {};
+ foreach my $related ($self->search_related($rel)) {
+ my $id_str = join("\0", $related->id);
+ next if $copied->{$id_str};
+ $copied->{$id_str} = 1;
+ my $rel_copy = $related->copy($resolved);
}
+
}
return $new;
}