derived from L<DBIx::Class::ResultSource> objects.
Row objects are returned from L<DBIx::Class::ResultSet>s using the
-L<DBIx::Class::ResultSet/create>, L<DBIx::Class::ResultSet/find>,
-L<DBIx::Class::ResultSet/next> and L<DBIx::Class::ResultSet/all> methods.
+L<create|DBIx::Class::ResultSet/create>, L<find|DBIx::Class::ResultSet/find>,
+L<next|DBIx::Class::ResultSet/next> and L<all|DBIx::Class::ResultSet/all> methods,
+as well as invocations of 'single' (
+L<belongs_to|DBIx::Class::Relationship/belongs_to>,
+L<has_one|DBIx::Class::Relationship/has_one> or
+L<might_have|DBIx::Class::Relationship/might_have>)
+relationship accessors of L<DBIx::Class::Row> objects.
=head1 METHODS
sub __new_related_find_or_new_helper {
my ($self, $relname, $data) = @_;
if ($self->__their_pk_needs_us($relname, $data)) {
+# print STDERR "PK needs us\n";
+# print STDERR "Data: ", Data::Dumper::Dumper($data);
return $self->result_source
->related_source($relname)
->resultset
->new_result($data);
}
if ($self->result_source->pk_depends_on($relname, $data)) {
+# print STDERR "PK depends on\n";
return $self->result_source
->related_source($relname)
->resultset
->find_or_create($data);
}
+# print STDERR "Neither, find_or_new\n";
return $self->find_or_new_related($relname, $data);
}
my ($self, $relname, $data) = @_;
my $source = $self->result_source;
my $reverse = $source->reverse_relationship_info($relname);
+# print STDERR "Found reverse rel info: ", Data::Dumper::Dumper($reverse);
my $rel_source = $source->related_source($relname);
my $us = { $self->get_columns };
+# print STDERR "Test on self cols: ", Data::Dumper::Dumper($us);
foreach my $key (keys %$reverse) {
# if their primary key depends on us, then we have to
# just create a result and we'll fill it out afterwards
- return 1 if $rel_source->pk_depends_on($key, $us);
+ my $dep = $rel_source->pk_depends_on($key, $us);
+ if($dep) {
+# print STDERR "Assigning $self to $key\n";
+ $data->{$key} = $self;
+ return 1;
+ }
+# return 1 if $rel_source->pk_depends_on($key, $us);
}
return 0;
}
$new->result_source($source);
}
+# print "Source ", $source->source_name, " is $new\n";
if ($attrs) {
$new->throw_exception("attrs must be a hashref")
unless ref($attrs) eq 'HASH';
if ($info && $info->{attrs}{accessor}
&& $info->{attrs}{accessor} eq 'single')
{
+# print STDERR "Single $key ", Data::Dumper::Dumper($attrs);
+# print STDERR "from $class to: $info->{class}\n";
my $rel_obj = delete $attrs->{$key};
if(!Scalar::Util::blessed($rel_obj)) {
$rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
$new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
$related->{$key} = $rel_obj;
+# print STDERR "Related :", join(", ", keys %$related), "\n";
next;
} elsif ($info && $info->{attrs}{accessor}
&& $info->{attrs}{accessor} eq 'multi'
&& ref $attrs->{$key} eq 'ARRAY') {
+# print STDERR "Multi $key ", Data::Dumper::Dumper($attrs);
+# print STDERR "from $class to: $info->{class}\n";
my $others = delete $attrs->{$key};
foreach my $rel_obj (@$others) {
if(!Scalar::Util::blessed($rel_obj)) {
$new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
}
$related->{$key} = $others;
+# print STDERR "Related :", join(", ", keys %$related), "\n";
next;
} elsif ($info && $info->{attrs}{accessor}
&& $info->{attrs}{accessor} eq 'filter')
$inflated->{$key} = $attrs->{$key};
next;
}
+# print STDERR "Done :", join(", ", keys %$related), "\n";
}
$new->throw_exception("No such column $key on $class")
unless $class->has_column($key);
my @pri = $self->primary_columns;
REL: foreach my $relname (keys %related_stuff) {
-
+# print STDERR "Looking at: $relname\n";
my $rel_obj = $related_stuff{$relname};
next REL unless (Scalar::Util::blessed($rel_obj)
&& $rel_obj->isa('DBIx::Class::Row'));
+# print STDERR "Check pk: from ", $source->source_name, " to $relname\n";
+# print STDERR "With ", Data::Dumper::Dumper({ $rel_obj->get_columns });
next REL unless $source->pk_depends_on(
$relname, { $rel_obj->get_columns }
);
-
+# print STDERR "$rel_obj\n";
+# print STDERR "in_storage: ", $rel_obj->in_storage, "\n";
+# print STDERR "Inserting $relname\n";
$rel_obj->insert();
$self->set_from_related($relname, $rel_obj);
delete $related_stuff{$relname};
}
}
+# print STDERR "self $self\n";
+# print STDERR "self in_storage ", $self->in_storage, "\n";
+# print STDERR "Ran out of rels, insert ", $source->source_name, "\n";
my $updated_cols = $source->storage->insert($source, { $self->get_columns });
$self->set_columns($updated_cols);
+ $self->in_storage(1);
+# print STDERR "$self\n";
## PK::Auto
my @auto_pri = grep {
my $reverse = $source->reverse_relationship_info($relname);
foreach my $obj (@cands) {
$obj->set_from_related($_, $self) for keys %$reverse;
+# my $them = { %{$obj->{_relationship_data} || {} }, $obj->get_inflated_columns };
my $them = { $obj->get_inflated_columns };
+# print STDERR "Does $relname need our PK?\n";
if ($self->__their_pk_needs_us($relname, $them)) {
- $obj = $self->find_or_create_related($relname, $them);
+# print STDERR "Yes\n";
+ # $obj = $self->find_or_create_related($relname, $them);
+ $obj->insert();
} else {
+# print STDERR "No\n";
$obj->insert();
}
}
$rollback_guard->commit;
}
- $self->in_storage(1);
+# $self->in_storage(1);
undef $self->{_orig_ident};
return $self;
}
values to locate the row.
The object is still perfectly usable, but L</in_storage> will
-now return 0 and the object must reinserted using L</insert>
+now return 0 and the object must be reinserted using L</insert>
before it can be used to L</update> the row again.
If you delete an object in a class with a C<has_many> relationship, an
If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
will be deflated and returned.
+Note that if you used the C<columns> or the C<select/as>
+L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
+which C<$row> was derived, and B<did not include> C<$columnname> in the list,
+this method will return C<undef> even if the database contains some value.
+
To retrieve all loaded column values as a hash, use L</get_columns>.
=cut
Sets a raw column value. If the new value is different from the old one,
the column is marked as dirty for when you next call L</update>.
-If passed an object or reference as a value, this will happily attempt
-store it, and a later L</insert> or L</update> will try and
+If passed an object or reference as a value, this method will happily
+attempt to store it, and a later L</insert> or L</update> will try and
stringify/numify as appropriate. To set an object to be deflated
instead, see L</set_inflated_columns>.
{
my $rel = delete $upd->{$key};
$self->set_from_related($key => $rel);
- $self->{_relationship_data}{$key} = $rel;
+ $self->{_relationship_data}{$key} = $rel;
} elsif ($info && $info->{attrs}{accessor}
- && $info->{attrs}{accessor} eq 'multi'
- && ref $upd->{$key} eq 'ARRAY') {
- my $others = delete $upd->{$key};
- foreach my $rel_obj (@$others) {
- if(!Scalar::Util::blessed($rel_obj)) {
- $rel_obj = $self->create_related($key, $rel_obj);
- }
- }
- $self->{_relationship_data}{$key} = $others;
-# $related->{$key} = $others;
- next;
+ && $info->{attrs}{accessor} eq 'multi') {
+ $self->throw_exception(
+ "Recursive update is not supported over relationships of type multi ($key)"
+ );
}
elsif ($self->has_column($key)
&& exists $self->column_info($key)->{_inflate_info})
{
- $self->set_inflated_column($key, delete $upd->{$key});
+ $self->set_inflated_column($key, delete $upd->{$key});
}
}
}
=item Arguments: $columnname, $value
-=item Returns: The value set
+=item Returns: The value sent to storage
=back