DBIx-Class-Valiant

 view release on metacpan or  search on metacpan

lib/DBIx/Class/Valiant/Result.pm  view on Meta::CPAN

  }

  debug 2, "About to run validations for @{[$self]} on insert";
  if($self->auto_validation) {
    $self->validate(%args) unless $self->{__valiant_donot_insert} || $self->{__valiant_add};
  }

  if($self->errors->size) {
    debug 2, "Skipping insert for @{[$self]} because its invalid";
    return $self;
  } else {
    debug 2, "proceeding to insert  @{[$self]} because its valid";
  }

  if($self->{__valiant_donot_insert} || $self->{__valiant_add}) {
    debug 2, "Skipping insert for @{[$self]} because its probably and _add";
    return $self;
  }
  my $ret = $self->next::method(@args);
  # TODO could probably do the merge errors from related here
  return $ret;
}

sub _nested_info_for_related {
  my ($self, $related) = @_;
  my %nested = $self->result_class->accept_nested_for;
  my %info = %{ $nested{$related}||+{} };  
  return %info;
}

sub _related_allow_destroy {
  my ($self, $related) = @_;
  my %info = $self->_nested_info_for_related($related);
  if(my $proto = $info{allow_destroy}) {
    my $allow_or_not = (ref($proto)||'' eq 'CODE') ? $proto->($self) : $proto;
    return $allow_or_not;
  }
  return 0;
}

sub _related_delete_omitted {
  my ($self, $related) = @_;
  my %info = $self->_nested_info_for_related($related);
  if(my $proto = $info{delete_omitted}) {
    my $delete_or_not = (ref($proto)||'' eq 'CODE') ? $proto->($self) : $proto;
    return $delete_or_not;
  }
  return 0;
}

sub _related_limit {
  my ($self, $related) = @_;
  my %info = $self->_nested_info_for_related($related);
  if(my $limit_proto = $info{limit}) {
    my $limit = (ref($limit_proto)||'' eq 'CODE') ? $limit_proto->($self) : $limit_proto;
    return 1, $limit;
  }
  return 0, undef;
}

sub update {
  my ($self, $upd) = @_;
  my $context = delete($upd->{__context})||[];
  my @context = ref($context)||'' eq 'ARRAY' ? @$context : ($context);
  push @context, 'update' unless grep { $_ eq 'update' } @context;

  my %related = ();
  my %nested = $self->result_class->accept_nested_for;

  foreach my $associated(keys %nested) {
    $related{$associated} = delete($upd->{$associated})
      if exists($upd->{$associated});
  }

  # Remove any relationed keys we didn't find with the allows nested
  my @rel_names = $self->result_source->relationships();
  my @m2m_names = keys  %{ $self->result_class->_m2m_metadata ||+{} };
  debug 1, "Found related for @{[ ref $self ]} of @{[ join ',', @rel_names ]}";

  my %found = map { $_ => delete($upd->{$_})  } @rel_names, @m2m_names; # backcompat with old perl

  if(grep { defined $_ } values %found) {
    my $related = join(', ', grep { $found{$_} } keys %found);
    die "You are trying to create a relationship ($related) on @{[ $self ]} without setting 'accept_nested_for'";
  }

  my %validate_args = (context => \@context) if @context;

  $self->set_inflated_columns($upd) if $upd;

  foreach my $related(keys %related) {

    if(my $cb = $nested{$related}->{reject_if}) {
      next if $cb->($self, $related{$related});
    }

    my ($has_limit, $limit) = $self->_related_limit($related);
    if($has_limit) {
      my $num = scalar @{$related{$related}};
      DBIx::Class::Valiant::Util::Exception::TooManyRows
        ->throw(
          limit=>$limit,
          attempted=>$num,
          related=>$related,
          me=>$self->result_source->name,
        ) if $num > $limit;
    }

    debug 2, "Setting related '$related' for @{[ ref $self ]} ";

    #$self->update_or_create_related($related, $related{$related});
    $self->{_valiant_nested_info} = $nested{$related};
    $self->set_related_from_params($related, $related{$related});

    delete $self->{_valiant_nested_info};
  }

  debug 2, "Checking if row for update is marked for deletion @{[$self]}";
  if($self->is_marked_for_deletion) {
    debug 2, "Skipping update for @{[$self]} because its marked for deletion";
    return $self;



( run in 2.635 seconds using v1.01-cache-2.11-cpan-364913b4093 )