$rs = $cd->related_resultset('tracks'); # has_many relationship
$rs = $cd->tracks;
-This is the recommended way to transverse through relationships, based
+This is the recommended way to traverse through relationships, based
on the L</accessor> name given in the relationship definition.
This will return either a L<Result|DBIx::Class::Manual::ResultClass> or a
sub related_resultset {
my $self = shift;
+
$self->throw_exception("Can't call *_related as class methods")
unless ref $self;
+
my $rel = shift;
my $rel_info = $self->relationship_info($rel);
- $self->throw_exception( "No such relationship ${rel}" )
+ $self->throw_exception( "No such relationship '$rel'" )
unless $rel_info;
return $self->{related_resultsets}{$rel} ||= do {
if (@_ > 1 && (@_ % 2 == 1));
my $query = ((@_ > 1) ? {@_} : shift);
- my $source = $self->result_source;
+ my $rsrc = $self->result_source;
# condition resolution may fail if an incomplete master-object prefetch
# is encountered - that is ok during prefetch construction (not yet in_storage)
my ($cond, $is_crosstable) = try {
- $source->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel )
+ $rsrc->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel )
}
catch {
if ($self->in_storage) {
# keep in mind that the following if() block is part of a do{} - no return()s!!!
if ($is_crosstable) {
$self->throw_exception (
- "A cross-table relationship condition returned for statically declared '$rel'")
- unless ref $rel_info->{cond} eq 'CODE';
+ "A cross-table relationship condition returned for statically declared '$rel'"
+ ) unless ref $rel_info->{cond} eq 'CODE';
# A WHOREIFFIC hack to reinvoke the entire condition resolution
# with the correct alias. Another way of doing this involves a
# root alias as 'me', instead of $rel (as opposed to invoking
# $rs->search_related)
- local $source->{_relationships}{me} = $source->{_relationships}{$rel}; # make the fake 'me' rel
- my $obj_table_alias = lc($source->source_name) . '__row';
+ local $rsrc->{_relationships}{me} = $rsrc->{_relationships}{$rel}; # make the fake 'me' rel
+ my $obj_table_alias = lc($rsrc->source_name) . '__row';
$obj_table_alias =~ s/\W+/_/g;
- $source->resultset->search(
+ $rsrc->resultset->search(
$self->ident_condition($obj_table_alias),
{ alias => $obj_table_alias },
)->search_related('me', $query, $attrs)
# at some point what it does. Also the entire UNRESOLVABLE_CONDITION
# business seems shady - we could simply not query *at all*
if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
- my $reverse = $source->reverse_relationship_info($rel);
+ my $reverse = $rsrc->reverse_relationship_info($rel);
foreach my $rev_rel (keys %$reverse) {
if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
weaken($attrs->{related_objects}{$rev_rel}[0] = $self);
}
$query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
- $self->result_source->related_source($rel)->resultset->search(
+ $rsrc->related_source($rel)->resultset->search(
$query, $attrs
);
}
=cut
sub count_related {
- my $self = shift;
- return $self->search_related(@_)->count;
+ shift->search_related(@_)->count;
}
=head2 new_related
if (ref $self) { # cdbi calls this as a class method, /me vomits
my $rsrc = $self->result_source;
- my (undef, $crosstable, $relcols) = $rsrc->_resolve_condition (
+ my (undef, $crosstable, $cond_targets) = $rsrc->_resolve_condition (
$rsrc->relationship_info($rel)->{cond}, $rel, $self, $rel
);
$self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")
if $crosstable;
- if (@{$relcols || []} and @$relcols = grep { ! exists $values->{$_} } @$relcols) {
+ if (my @unspecified_rel_condition_chunks = grep { ! exists $values->{$_} } @{$cond_targets||[]} ) {
$self->throw_exception(sprintf (
"Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
$rel,
- map { "'$_'" } @$relcols
+ map { "'$_'" } @unspecified_rel_condition_chunks
));
}
}
=cut
sub find_related {
- my $self = shift;
- my $rel = shift;
- return $self->search_related($rel)->find(@_);
+ #my ($self, $rel, @args) = @_;
+ return shift->search_related(shift)->find(@_);
}
=head2 find_or_new_related
=cut
sub update_or_create_related {
- my $self = shift;
- my $rel = shift;
- return $self->related_resultset($rel)->update_or_create(@_);
+ #my ($self, $rel, @args) = @_;
+ shift->related_resultset(shift)->update_or_create(@_);
}
=head2 set_from_related
my $rsrc = $self->result_source;
my $rel_info = $rsrc->relationship_info($rel)
- or $self->throw_exception( "No such relationship ${rel}" );
+ or $self->throw_exception( "No such relationship '$rel'" );
if (defined $f_obj) {
my $f_class = $rel_info->{class};
- $self->throw_exception( "Object $f_obj isn't a ".$f_class )
+ $self->throw_exception( "Object '$f_obj' isn't a ".$f_class )
unless blessed $f_obj and $f_obj->isa($f_class);
}
#
# sanity check - currently throw when a complex coderef rel is encountered
# FIXME - should THROW MOAR!
- my ($cond, $crosstable, $relcols) = $rsrc->_resolve_condition (
+ my ($cond, $crosstable, $cond_targets) = $rsrc->_resolve_condition (
$rel_info->{cond}, $f_obj, $rel, $rel
);
$self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")
$self->throw_exception(sprintf (
"Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
$rel,
- map { "'$_'" } @$relcols
- )) if @{$relcols || []};
+ map { "'$_'" } @$cond_targets
+ )) if $cond_targets;
$self->set_columns($cond);