X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRelationship%2FBase.pm;h=e660d146e907ad25b8f35b9246ca00ce2cdd50b4;hb=0c11ad0ee5c8407f6b87d6e15c62a1b445076dc0;hp=506d51d5b04918e444810c351a8da55b4a1464b6;hpb=78b948c3f914722aaecae145119500aa0f46ac74;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index 506d51d..e660d14 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -167,7 +167,7 @@ L and the resulting SQL will be used verbatim as the C clause of the C statement associated with this relationship. While every coderef-based condition must return a valid C clause, it may -elect to additionally return a simplified join-free condition hashref when +elect to additionally return a simplified join-free condition hashref when invoked as C<< $row_object->relationship >>, as opposed to C<< $rs->related_resultset('relationship') >>. In this case C<$row_object> is passed to the coderef as C<< $args->{self_rowobj} >>, so a user can do the @@ -249,6 +249,12 @@ command immediately before C. =item proxy =E $column | \@columns | \%column +The 'proxy' attribute can be used to retrieve values, and to perform +updates if the relationship has 'cascade_update' set. The 'might_have' +and 'has_one' relationships have this set by default; if you want a proxy +to update across a 'belongs_to' relationship, you must set the attribute +yourself. + =over 4 =item \@columns @@ -256,23 +262,31 @@ command immediately before C. An arrayref containing a list of accessors in the foreign class to create in the main class. If, for example, you do the following: - MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes', + MyApp::Schema::CD->might_have(liner_notes => 'MyApp::Schema::LinerNotes', undef, { proxy => [ qw/notes/ ], }); -Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do: +Then, assuming MyApp::Schema::LinerNotes has an accessor named notes, you can do: - my $cd = MyDB::Schema::CD->find(1); + my $cd = MyApp::Schema::CD->find(1); $cd->notes('Notes go here'); # set notes -- LinerNotes object is # created if it doesn't exist +For a 'belongs_to relationship, note the 'cascade_update': + + MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd, + { proxy => ['title'], cascade_update => 1 } + ); + $track->title('New Title'); + $track->update; # updates title in CD + =item \%column A hashref where each key is the accessor you want installed in the main class, and its value is the name of the original in the fireign class. - MyDB::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { + MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { proxy => { cd_title => 'title' }, }); @@ -282,7 +296,7 @@ This will create an accessor named C on the C<$track> row object. NOTE: you can pass a nested struct too, for example: - MyDB::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { + MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { proxy => [ 'year', { cd_title => 'title' } ], }); @@ -331,6 +345,10 @@ C relationships. You can disable this behaviour on a per-relationship basis by supplying C<< cascade_update => 0 >> in the relationship attributes. +The C relationship does not update across relationships +by default, so if you have a 'proxy' attribute on a belongs_to and want to +use 'update' on it, you muse set C<< cascade_update => 1 >>. + This is not a RDMS style cascade update - it purely means that when an object has update called on it, all the related objects also have update called. It will not change foreign keys automatically - @@ -444,9 +462,9 @@ sub related_resultset { # 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'; + $obj_table_alias =~ s/\W+/_/g; $source->resultset->search( $self->ident_condition($obj_table_alias), @@ -461,11 +479,9 @@ sub related_resultset { my $reverse = $source->reverse_relationship_info($rel); foreach my $rev_rel (keys %$reverse) { if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') { - $attrs->{related_objects}{$rev_rel} = [ $self ]; - weaken $attrs->{related_object}{$rev_rel}[0]; + weaken($attrs->{related_objects}{$rev_rel}[0] = $self); } else { - $attrs->{related_objects}{$rev_rel} = $self; - weaken $attrs->{related_object}{$rev_rel}; + weaken($attrs->{related_objects}{$rev_rel} = $self); } } } @@ -555,7 +571,7 @@ on it. =cut sub new_related { - my ($self, $rel, $values, $attrs) = @_; + my ($self, $rel, $values) = @_; # FIXME - this is a bad position for this (also an identical copy in # set_from_related), but I have no saner way to hook, and I absolutely @@ -584,8 +600,7 @@ sub new_related { } } - my $row = $self->search_related($rel)->new($values, $attrs); - return $row; + return $self->search_related($rel)->new_result($values); } =head2 create_related @@ -829,9 +844,9 @@ Removes the link between the current object and the related object. Note that the related object itself won't be deleted unless you call ->delete() on it. This method just removes the link between the two objects. -=head1 AUTHORS +=head1 AUTHOR AND CONTRIBUTORS -Matt S. Trout +See L and L in DBIx::Class =head1 LICENSE