+# returns DBIx::Class::ResultSource::column_info as a hash indexed by column accessor || name
+sub _get_columns_by_accessor {
+ my $self = shift;
+ my $source = $self->result_source;
+ my %columns;
+ for my $name ( $source->columns ) {
+ my $info = $source->column_info($name);
+ $info->{name} = $name;
+ $columns{ $info->{accessor} || $name } = $info;
+ }
+ return %columns;
+}
+
+# Arguments: $name, $updates, $object, $info, $if_not_submitted
+
+sub _update_relation {
+ my ( $self, $name, $updates, $object, $info, $if_not_submitted ) = @_;
+ my $related_result =
+ $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 );
+ }
+ else {
+ $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;
+
+ # an arrayref is only valid for has_many rels
+ if ( ref $updates eq 'ARRAY' ) {
+ my @updated_ids;
+ for my $sub_updates ( @{ $updates } ) {
+ my $sub_object = recursive_update(
+ resultset => $related_result,
+ updates => $sub_updates,
+ resolved => $resolved
+ );
+ push @updated_ids, $sub_object->id;
+ }
+ my @related_pks = $related_result->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 } );
+ }
+ }
+ }
+ else {
+ 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_result,
+ updates => $updates,
+ object => $object->$name
+ );
+ }
+ else {
+ $sub_object = recursive_update(
+ resultset => $related_result,
+ updates => $updates,
+ resolved => $resolved
+ );
+ }
+ }
+ elsif ( !ref $updates ) {
+ $sub_object = $related_result->find($updates)
+ unless (
+ !$updates
+ && ( exists $info->{attrs}{join_type}
+ && $info->{attrs}{join_type} eq 'LEFT' )
+ );
+ }
+ $object->set_from_related( $name, $sub_object )
+ unless (
+ !$sub_object
+ && !$updates
+ && ( exists $info->{attrs}{join_type}
+ && $info->{attrs}{join_type} eq 'LEFT' )
+ );
+ }