X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRelationship%2FBase.pm;h=a41d6b4df0b1d15874a6df2da4f58f93f087e2de;hb=a5fc497548f9f980d3fd1deb7b7cb9095d079651;hp=cd9749f519df73c3cac2e2cb9a6cdb5759d0d45f;hpb=3d0733aac1d6b24f71d0836ff3418ea8cdeba97a;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index cd9749f..a41d6b4 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -54,9 +54,16 @@ source, indicated by its class name. The condition argument describes the C clause of the C expression used to connect the two sources when creating SQL queries. -To create simple equality joins, supply a hashref containing the -remote table column name as the key(s), and the local table column -name as the value(s), for example given: +=head4 Simple equality + +To create simple equality joins, supply a hashref containing the remote +table column name as the key(s) prefixed by C<'foreign.'>, and the +corresponding local table column name as the value(s) prefixed by C<'self.'>. +Both C and C are pseudo aliases and must be entered +literally. They will be replaced with the actual correct table alias +when the SQL is produced. + +For example given: My::Schema::Author->has_many( books => 'My::Schema::Book', @@ -75,10 +82,6 @@ This describes a relationship between the C table and the C table where the C table has a column C containing the ID value of the C. -C and C are pseudo aliases and must be entered -literally. They will be replaced with the actual correct table alias -when the SQL is produced. - Similarly: My::Schema::Book->has_many( @@ -103,9 +106,11 @@ will result in the C clause: This describes the relationship from C to C, where the C table refers to a publisher and a type (e.g. "paperback"): +=head4 Multiple groups of simple equality conditions + As is the default in L, the key-value pairs will be -Ced in the result. C can be achieved with an arrayref, for -example a condition like: +Ced in the resulting C clause. An C can be achieved with +an arrayref. For example a condition like: My::Schema::Item->has_many( related_item_links => My::Schema::Item::Links, @@ -125,6 +130,14 @@ This describes the relationship from C to C, where C is a many-to-many linking table, linking items back to themselves in a peer fashion (without a "parent-child" designation) +=head4 Custom join conditions + + NOTE: The custom join condition specification mechanism is capable of + generating JOIN clauses of virtually unlimited complexity. This may limit + your ability to traverse some of the more involved relationship chains the + way you expect, *and* may bring your RDBMS to its knees. Exercise care + when declaring relationships as described here. + To specify joins which describe more than a simple equality of column values, the custom join condition coderef syntax can be used. For example: @@ -206,13 +219,13 @@ With the bind values: '4', '1990', '1979' Note that in order to be able to use -L<< $row->create_related|DBIx::Class::Relationship::Base/create_related >>, +L<< $result->create_related|DBIx::Class::Relationship::Base/create_related >>, the coderef must not only return as its second such a "simple" condition hashref which does not depend on joins being available, but the hashref must contain only plain values/deflatable objects, such that the result can be passed directly to L. For instance the C constraint in the above example prevents the relationship -from being used to to create related objects (an exception will be thrown). +from being used to create related objects (an exception will be thrown). In order to allow the user to go truly crazy when generating a custom C clause, the C<$args> hashref passed to the subroutine contains some extra @@ -275,7 +288,7 @@ Then, assuming MyApp::Schema::LinerNotes has an accessor named notes, you can do For a 'belongs_to relationship, note the 'cascade_update': - MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd, + MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd, { proxy => ['title'], cascade_update => 1 } ); $track->title('New Title'); @@ -284,9 +297,9 @@ For a 'belongs_to relationship, note the 'cascade_update': =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. +and its value is the name of the original in the foreign class. - MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { + MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd', { proxy => { cd_title => 'title' }, }); @@ -296,7 +309,7 @@ This will create an accessor named C on the C<$track> result object. NOTE: you can pass a nested struct too, for example: - MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', { + MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd', { proxy => [ 'year', { cd_title => 'title' } ], }); @@ -423,8 +436,8 @@ $rel_name. =back # These pairs do the same thing - $row = $cd->related_resultset('artist')->single; # has_one relationship - $row = $cd->artist; + $result = $cd->related_resultset('artist')->single; # has_one relationship + $result = $cd->artist; $rs = $cd->related_resultset('tracks'); # has_many relationship $rs = $cd->tracks; @@ -627,8 +640,10 @@ sub new_related { if (ref $self) { # cdbi calls this as a class method, /me vomits my $rsrc = $self->result_source; + my $rel_info = $rsrc->relationship_info($rel) + or $self->throw_exception( "No such relationship '$rel'" ); my (undef, $crosstable, $cond_targets) = $rsrc->_resolve_condition ( - $rsrc->relationship_info($rel)->{cond}, $rel, $self, $rel + $rel_info->{cond}, $rel, $self, $rel ); $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")