- my ( $self, $name, $updates, $object, $info ) = @_;
-
- my $related_result =
- $self->related_resultset($name)->result_source->resultset;
- my $resolved =
- $self->result_source->resolve_condition( $info->{cond}, $name, $object );
-
- # warn 'resolved: ' . Dumper( $resolved ); use Data::Dumper;
- $resolved = undef
- if defined $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION && $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION == $resolved;
- if ( ref $updates->{$name} eq 'ARRAY' ) {
- for my $sub_updates ( @{ $updates->{$name} } ) {
- $sub_updates = { %$sub_updates, %$resolved } if $resolved && ref( $sub_updates ) eq 'HASH';
- my $sub_object =
- $related_result->recursive_update( $sub_updates );
+ my ( $self, $name, $updates, $object, $if_not_submitted ) = @_;
+
+ # this should never happen because we're checking the paramters passed to
+ # recursive_update, but just to be sure...
+ $object->throw_exception("No such relationship '$name' on ")
+ unless $object->has_relationship($name);
+
+ my $info = $object->result_source->relationship_info($name);
+
+ # get a related resultset without a condition
+ my $related_resultset =
+ $self->related_resultset($name)->result_source->resultset;
+ my $resolved;
+ if ( $self->result_source->can('_resolve_condition') ) {
+ $resolved =
+ $self->result_source->_resolve_condition( $info->{cond}, $name,
+ $object );
+ }
+
+ # warn "$name resolved: " . Dumper( $resolved ); use Data::Dumper;
+ $resolved = {}
+ if defined $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION
+ && $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION
+ == $resolved;
+
+ my $rel_col_cnt = scalar keys %{ $info->{cond} };
+ use Data::Dumper;
+ warn "RELINFO for $name: " . Dumper($info);
+ warn "REL_COL_CNT: $rel_col_cnt";
+
+ #warn "REV RELINFO for $name: " . Dumper($revrelinfo);
+
+ # the only valid datatype for a has_many rels is an arrayref
+ if ( $info->{attrs}{accessor} eq 'multi') {
+ $self->throw_exception( "data for has_many relationship '$name' must be an arrayref")
+ unless ref $updates eq 'ARRAY';
+
+ my @updated_ids;
+ for my $sub_updates ( @{$updates} ) {
+ warn "updating $name";
+ my $sub_object = recursive_update(
+ resultset => $related_resultset,
+ updates => $sub_updates,
+ resolved => $resolved
+ );
+ push @updated_ids, $sub_object->id;
+ }
+ my @related_pks = $related_resultset->result_source->primary_columns;
+ if ( defined $if_not_submitted && $if_not_submitted eq 'delete' ) {
+
+ # only handles related result classes with single primary keys
+ if ( 1 == scalar @related_pks ) {
+ $object->$name->search(
+ { $related_pks[0] => { -not_in => \@updated_ids } } )
+ ->delete;
+ }
+ }
+ elsif ( defined $if_not_submitted
+ && $if_not_submitted eq 'set_to_null' )
+ {
+
+ # only handles related result classes with single primary keys
+ if ( 1 == scalar @related_pks ) {
+ my @fk = keys %$resolved;
+ $object->$name->search(
+ { $related_pks[0] => { -not_in => \@updated_ids } } )
+ ->update( { $fk[0] => undef } );
+ }
+ }
+ }
+ elsif ($info->{attrs}{accessor} eq 'single'
+ || $info->{attrs}{accessor} eq 'filter' )
+ {
+ my $sub_object;
+ if ( ref $updates ) {
+
+ # for might_have relationship
+ if ( $info->{attrs}{accessor} eq 'single'
+ && defined $object->$name )
+ {
+ $sub_object = recursive_update(
+ resultset => $related_resultset,
+ updates => $updates,
+ object => $object->$name
+ );
+ }
+ else {
+ $sub_object = recursive_update(
+ resultset => $related_resultset,
+ updates => $updates,
+ resolved => $resolved
+ );
+ }
+ }
+ elsif ( !ref $updates ) {
+ $sub_object = $related_resultset->find($updates)
+ unless (
+ !$updates
+ && ( exists $info->{attrs}{join_type}
+ && $info->{attrs}{join_type} eq 'LEFT' )
+ );