Switch UNRESOLVABLE_CONDITION to an _Util constant
[dbsrgits/DBIx-Class-Historic.git] / lib / DBIx / Class / Relationship / Base.pm
CommitLineData
55e2d745 1package DBIx::Class::Relationship::Base;
2
3use strict;
4use warnings;
5
1edd1722 6use base qw/DBIx::Class/;
6298a324 7
8use Scalar::Util qw/weaken blessed/;
ed7ab0f4 9use Try::Tiny;
facd0e8e 10use DBIx::Class::_Util 'UNRESOLVABLE_CONDITION';
fd323bf1 11use namespace::clean;
55e2d745 12
75d07914 13=head1 NAME
55e2d745 14
8918977e 15DBIx::Class::Relationship::Base - Inter-table relationships
55e2d745 16
17=head1 SYNOPSIS
18
6c4f4d69 19 __PACKAGE__->add_relationship(
20 spiders => 'My::DB::Result::Creatures',
21 sub {
22 my $args = shift;
23 return {
24 "$args->{foreign_alias}.id" => { -ident => "$args->{self_alias}.id" },
25 "$args->{foreign_alias}.type" => 'arachnid'
26 };
27 },
28 );
13523f29 29
55e2d745 30=head1 DESCRIPTION
31
30236e47 32This class provides methods to describe the relationships between the
33tables in your database model. These are the "bare bones" relationships
75d07914 34methods, for predefined ones, look in L<DBIx::Class::Relationship>.
55e2d745 35
36=head1 METHODS
37
8091aa91 38=head2 add_relationship
503536d5 39
27f01d1f 40=over 4
41
a5f5e470 42=item Arguments: $rel_name, $foreign_class, $condition, $attrs
27f01d1f 43
44=back
30236e47 45
a5f5e470 46 __PACKAGE__->add_relationship('rel_name',
6c4f4d69 47 'Foreign::Class',
13523f29 48 $condition, $attrs);
49
50Create a custom relationship between one result source and another
51source, indicated by its class name.
503536d5 52
406734bb 53=head3 condition
54
6c4f4d69 55The condition argument describes the C<ON> clause of the C<JOIN>
56expression used to connect the two sources when creating SQL queries.
30236e47 57
5d2588cc 58=head4 Simple equality
59
60To create simple equality joins, supply a hashref containing the remote
61table column name as the key(s) prefixed by C<'foreign.'>, and the
62corresponding local table column name as the value(s) prefixed by C<'self.'>.
63Both C<foreign> and C<self> are pseudo aliases and must be entered
64literally. They will be replaced with the actual correct table alias
65when the SQL is produced.
66
67For example given:
503536d5 68
6c4f4d69 69 My::Schema::Author->has_many(
70 books => 'My::Schema::Book',
71 { 'foreign.author_id' => 'self.id' }
72 );
503536d5 73
6c4f4d69 74A query like:
75
76 $author_rs->search_related('books')->next
503536d5 77
6c4f4d69 78will result in the following C<JOIN> clause:
79
80 ... FROM author me LEFT JOIN book books ON books.author_id = me.id ...
503536d5 81
13523f29 82This describes a relationship between the C<Author> table and the
83C<Book> table where the C<Book> table has a column C<author_id>
84containing the ID value of the C<Author>.
85
13523f29 86Similarly:
5271499d 87
6c4f4d69 88 My::Schema::Book->has_many(
89 editions => 'My::Schema::Edition',
90 {
91 'foreign.publisher_id' => 'self.publisher_id',
92 'foreign.type_id' => 'self.type_id',
93 }
94 );
95
96 ...
97
98 $book_rs->search_related('editions')->next
5271499d 99
13523f29 100will result in the C<JOIN> clause:
5271499d 101
6c4f4d69 102 ... FROM book me
103 LEFT JOIN edition editions ON
104 editions.publisher_id = me.publisher_id
105 AND editions.type_id = me.type_id ...
5271499d 106
13523f29 107This describes the relationship from C<Book> to C<Edition>, where the
108C<Edition> table refers to a publisher and a type (e.g. "paperback"):
109
5d2588cc 110=head4 Multiple groups of simple equality conditions
111
13523f29 112As is the default in L<SQL::Abstract>, the key-value pairs will be
5d2588cc 113C<AND>ed in the resulting C<JOIN> clause. An C<OR> can be achieved with
114an arrayref. For example a condition like:
13523f29 115
6c4f4d69 116 My::Schema::Item->has_many(
117 related_item_links => My::Schema::Item::Links,
118 [
119 { 'foreign.left_itemid' => 'self.id' },
120 { 'foreign.right_itemid' => 'self.id' },
121 ],
122 );
13523f29 123
6c4f4d69 124will translate to the following C<JOIN> clause:
13523f29 125
6c4f4d69 126 ... FROM item me JOIN item_relations related_item_links ON
127 related_item_links.left_itemid = me.id
128 OR related_item_links.right_itemid = me.id ...
13523f29 129
6c4f4d69 130This describes the relationship from C<Item> to C<Item::Links>, where
131C<Item::Links> is a many-to-many linking table, linking items back to
132themselves in a peer fashion (without a "parent-child" designation)
13523f29 133
84d8c2ad 134=head4 Custom join conditions
135
5d2588cc 136 NOTE: The custom join condition specification mechanism is capable of
137 generating JOIN clauses of virtually unlimited complexity. This may limit
138 your ability to traverse some of the more involved relationship chains the
139 way you expect, *and* may bring your RDBMS to its knees. Exercise care
140 when declaring relationships as described here.
141
6c4f4d69 142To specify joins which describe more than a simple equality of column
143values, the custom join condition coderef syntax can be used. For
144example:
13523f29 145
6c4f4d69 146 My::Schema::Artist->has_many(
147 cds_80s => 'My::Schema::CD',
13523f29 148 sub {
6c4f4d69 149 my $args = shift;
13523f29 150
6c4f4d69 151 return {
152 "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
153 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
154 };
155 }
156 );
13523f29 157
6c4f4d69 158 ...
13523f29 159
6c4f4d69 160 $artist_rs->search_related('cds_80s')->next;
13523f29 161
6c4f4d69 162will result in the C<JOIN> clause:
13523f29 163
6c4f4d69 164 ... FROM artist me LEFT JOIN cd cds_80s ON
165 cds_80s.artist = me.artistid
166 AND cds_80s.year < ?
167 AND cds_80s.year > ?
13523f29 168
6c4f4d69 169with the bind values:
13523f29 170
6c4f4d69 171 '1990', '1979'
13523f29 172
6c4f4d69 173C<< $args->{foreign_alias} >> and C<< $args->{self_alias} >> are supplied the
174same values that would be otherwise substituted for C<foreign> and C<self>
175in the simple hashref syntax case.
176
177The coderef is expected to return a valid L<SQL::Abstract> query-structure, just
178like what one would supply as the first argument to
179L<DBIx::Class::ResultSet/search>. The return value will be passed directly to
180L<SQL::Abstract> and the resulting SQL will be used verbatim as the C<ON>
181clause of the C<JOIN> statement associated with this relationship.
182
183While every coderef-based condition must return a valid C<ON> clause, it may
8273e845 184elect to additionally return a simplified join-free condition hashref when
dad42de6 185invoked as C<< $result->relationship >>, as opposed to
186C<< $rs->related_resultset('relationship') >>. In this case C<$result> is
78b3d153 187passed to the coderef as C<< $args->{self_resultobj} >>, so a user can do the
6c4f4d69 188following:
189
190 sub {
191 my $args = shift;
192
193 return (
194 {
195 "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
196 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
197 },
78b3d153 198 $args->{self_resultobj} && {
199 "$args->{foreign_alias}.artist" => $args->{self_resultobj}->artistid,
6c4f4d69 200 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
201 },
202 );
13523f29 203 }
204
205Now this code:
206
207 my $artist = $schema->resultset("Artist")->find({ id => 4 });
208 $artist->cds_80s->all;
209
6c4f4d69 210Can skip a C<JOIN> altogether and instead produce:
13523f29 211
6c4f4d69 212 SELECT cds_80s.cdid, cds_80s.artist, cds_80s.title, cds_80s.year, cds_80s.genreid, cds_80s.single_track
213 FROM cd cds_80s
214 WHERE cds_80s.artist = ?
215 AND cds_80s.year < ?
216 AND cds_80s.year > ?
13523f29 217
218With the bind values:
219
220 '4', '1990', '1979'
221
6c4f4d69 222Note that in order to be able to use
47d7b769 223L<< $result->create_related|DBIx::Class::Relationship::Base/create_related >>,
6c4f4d69 224the coderef must not only return as its second such a "simple" condition
225hashref which does not depend on joins being available, but the hashref must
226contain only plain values/deflatable objects, such that the result can be
227passed directly to L<DBIx::Class::Relationship::Base/set_from_related>. For
228instance the C<year> constraint in the above example prevents the relationship
4a0eed52 229from being used to create related objects (an exception will be thrown).
6c4f4d69 230
231In order to allow the user to go truly crazy when generating a custom C<ON>
232clause, the C<$args> hashref passed to the subroutine contains some extra
233metadata. Currently the supplied coderef is executed as:
234
235 $relationship_info->{cond}->({
a446d7f8 236 self_resultsource => The resultsource instance on which rel_name is registered
237 rel_name => The relationship name (does *NOT* always match foreign_alias)
238
239 self_alias => The alias of the invoking resultset
240 foreign_alias => The alias of the to-be-joined resultset (does *NOT* always match rel_name)
241
1adbd3fc 242 # only one of these (or none at all) will ever be supplied to aid in the
243 # construction of a join-free condition
a446d7f8 244 self_resultobj => The invocant object itself in case of a $resultobj->$rel_name() call
1adbd3fc 245 foreign_resultobj => The related object in case of $resultobj->set_from_related($rel_name, $foreign_resultobj)
a446d7f8 246
247 # deprecated inconsistent names, will be forever available for legacy code
248 self_rowobj => Old deprecated slot for self_resultobj
249 foreign_relname => Old deprecated slot for rel_name
6c4f4d69 250 });
8091aa91 251
406734bb 252=head3 attributes
253
254The L<standard ResultSet attributes|DBIx::Class::ResultSet/ATTRIBUTES> may
255be used as relationship attributes. In particular, the 'where' attribute is
256useful for filtering relationships:
257
258 __PACKAGE__->has_many( 'valid_users', 'MyApp::Schema::User',
259 { 'foreign.user_id' => 'self.user_id' },
260 { where => { valid => 1 } }
261 );
262
263The following attributes are also valid:
8091aa91 264
265=over 4
266
267=item join_type
268
269Explicitly specifies the type of join to use in the relationship. Any SQL
270join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
271command immediately before C<JOIN>.
272
97c96475 273=item proxy =E<gt> $column | \@columns | \%column
274
9ab122aa 275The 'proxy' attribute can be used to retrieve values, and to perform
276updates if the relationship has 'cascade_update' set. The 'might_have'
277and 'has_one' relationships have this set by default; if you want a proxy
278to update across a 'belongs_to' relationship, you must set the attribute
279yourself.
280
97c96475 281=over 4
282
283=item \@columns
8091aa91 284
30236e47 285An arrayref containing a list of accessors in the foreign class to create in
8091aa91 286the main class. If, for example, you do the following:
d4daee7b 287
03460bef 288 MyApp::Schema::CD->might_have(liner_notes => 'MyApp::Schema::LinerNotes',
27f01d1f 289 undef, {
290 proxy => [ qw/notes/ ],
291 });
d4daee7b 292
03460bef 293Then, assuming MyApp::Schema::LinerNotes has an accessor named notes, you can do:
8091aa91 294
03460bef 295 my $cd = MyApp::Schema::CD->find(1);
30236e47 296 $cd->notes('Notes go here'); # set notes -- LinerNotes object is
297 # created if it doesn't exist
d4daee7b 298
9ab122aa 299For a 'belongs_to relationship, note the 'cascade_update':
300
a5fc4975 301 MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd,
9ab122aa 302 { proxy => ['title'], cascade_update => 1 }
303 );
304 $track->title('New Title');
305 $track->update; # updates title in CD
306
97c96475 307=item \%column
308
309A hashref where each key is the accessor you want installed in the main class,
4a0eed52 310and its value is the name of the original in the foreign class.
97c96475 311
a5fc4975 312 MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd', {
97c96475 313 proxy => { cd_title => 'title' },
314 });
315
dad42de6 316This will create an accessor named C<cd_title> on the C<$track> result object.
97c96475 317
318=back
319
320NOTE: you can pass a nested struct too, for example:
321
a5fc4975 322 MyApp::Schema::Track->belongs_to( cd => 'MyApp::Schema::CD', 'cd', {
97c96475 323 proxy => [ 'year', { cd_title => 'title' } ],
324 });
325
8091aa91 326=item accessor
327
328Specifies the type of accessor that should be created for the relationship.
329Valid values are C<single> (for when there is only a single related object),
330C<multi> (when there can be many), and C<filter> (for when there is a single
331related object, but you also want the relationship accessor to double as
332a column accessor). For C<multi> accessors, an add_to_* method is also
333created, which calls C<create_related> for the relationship.
334
3d618782 335=item is_foreign_key_constraint
336
337If you are using L<SQL::Translator> to create SQL for you and you find that it
fd323bf1 338is creating constraints where it shouldn't, or not creating them where it
3d618782 339should, set this attribute to a true or false value to override the detection
340of when to create constraints.
341
5f7ac523 342=item cascade_copy
343
344If C<cascade_copy> is true on a C<has_many> relationship for an
345object, then when you copy the object all the related objects will
fd323bf1 346be copied too. To turn this behaviour off, pass C<< cascade_copy => 0 >>
347in the C<$attr> hashref.
b7bbc39f 348
349The behaviour defaults to C<< cascade_copy => 1 >> for C<has_many>
350relationships.
5f7ac523 351
352=item cascade_delete
353
b7bbc39f 354By default, DBIx::Class cascades deletes across C<has_many>,
355C<has_one> and C<might_have> relationships. You can disable this
fd323bf1 356behaviour on a per-relationship basis by supplying
b7bbc39f 357C<< cascade_delete => 0 >> in the relationship attributes.
5f7ac523 358
359The cascaded operations are performed after the requested delete,
360so if your database has a constraint on the relationship, it will
361have deleted/updated the related records or raised an exception
362before DBIx::Class gets to perform the cascaded operation.
363
364=item cascade_update
365
b7bbc39f 366By default, DBIx::Class cascades updates across C<has_one> and
5f7ac523 367C<might_have> relationships. You can disable this behaviour on a
b7bbc39f 368per-relationship basis by supplying C<< cascade_update => 0 >> in
369the relationship attributes.
5f7ac523 370
9ab122aa 371The C<belongs_to> relationship does not update across relationships
372by default, so if you have a 'proxy' attribute on a belongs_to and want to
373use 'update' on it, you muse set C<< cascade_update => 1 >>.
374
cee0c9b1 375This is not a RDMS style cascade update - it purely means that when
376an object has update called on it, all the related objects also
377have update called. It will not change foreign keys automatically -
378you must arrange to do this yourself.
5f7ac523 379
e377d723 380=item on_delete / on_update
381
382If you are using L<SQL::Translator> to create SQL for you, you can use these
fd323bf1 383attributes to explicitly set the desired C<ON DELETE> or C<ON UPDATE> constraint
384type. If not supplied the SQLT parser will attempt to infer the constraint type by
e377d723 385interrogating the attributes of the B<opposite> relationship. For any 'multi'
fd323bf1 386relationship with C<< cascade_delete => 1 >>, the corresponding belongs_to
387relationship will be created with an C<ON DELETE CASCADE> constraint. For any
e377d723 388relationship bearing C<< cascade_copy => 1 >> the resulting belongs_to constraint
389will be C<ON UPDATE CASCADE>. If you wish to disable this autodetection, and just
fd323bf1 390use the RDBMS' default constraint type, pass C<< on_delete => undef >> or
e377d723 391C<< on_delete => '' >>, and the same for C<on_update> respectively.
392
13de943d 393=item is_deferrable
394
395Tells L<SQL::Translator> that the foreign key constraint it creates should be
396deferrable. In other words, the user may request that the constraint be ignored
397until the end of the transaction. Currently, only the PostgreSQL producer
398actually supports this.
399
2581038c 400=item add_fk_index
401
402Tells L<SQL::Translator> to add an index for this constraint. Can also be
403specified globally in the args to L<DBIx::Class::Schema/deploy> or
404L<DBIx::Class::Schema/create_ddl_dir>. Default is on, set to 0 to disable.
405
8091aa91 406=back
407
87c4e602 408=head2 register_relationship
409
27f01d1f 410=over 4
411
dad42de6 412=item Arguments: $rel_name, $rel_info
27f01d1f 413
414=back
71e65b39 415
30236e47 416Registers a relationship on the class. This is called internally by
71f9df37 417DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
71e65b39 418
55e2d745 419=cut
420
71e65b39 421sub register_relationship { }
422
27f01d1f 423=head2 related_resultset
424
425=over 4
426
dad42de6 427=item Arguments: $rel_name
27f01d1f 428
dad42de6 429=item Return Value: L<$related_resultset|DBIx::Class::ResultSet>
27f01d1f 430
431=back
30236e47 432
27f01d1f 433 $rs = $cd->related_resultset('artist');
30236e47 434
27f01d1f 435Returns a L<DBIx::Class::ResultSet> for the relationship named
dad42de6 436$rel_name.
30236e47 437
93711422 438=head2 $relationship_accessor
439
440=over 4
441
dad42de6 442=item Arguments: none
93711422 443
dad42de6 444=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | L<$related_resultset|DBIx::Class::ResultSet> | undef
93711422 445
446=back
447
448 # These pairs do the same thing
47d7b769 449 $result = $cd->related_resultset('artist')->single; # has_one relationship
450 $result = $cd->artist;
93711422 451 $rs = $cd->related_resultset('tracks'); # has_many relationship
452 $rs = $cd->tracks;
453
8ed69929 454This is the recommended way to traverse through relationships, based
93711422 455on the L</accessor> name given in the relationship definition.
456
dad42de6 457This will return either a L<Result|DBIx::Class::Manual::ResultClass> or a
93711422 458L<ResultSet|DBIx::Class::ResultSet>, depending on if the relationship is
459C<single> (returns only one row) or C<multi> (returns many rows). The
460method may also return C<undef> if the relationship doesn't exist for
461this instance (like in the case of C<might_have> relationships).
462
30236e47 463=cut
464
465sub related_resultset {
466 my $self = shift;
72c2540d 467
bc0c9800 468 $self->throw_exception("Can't call *_related as class methods")
469 unless ref $self;
72c2540d 470
30236e47 471 my $rel = shift;
d4daee7b 472
3d0733aa 473 return $self->{related_resultsets}{$rel}
474 if defined $self->{related_resultsets}{$rel};
475
476 return $self->{related_resultsets}{$rel} = do {
3b4c4d72 477
478 my $rel_info = $self->relationship_info($rel)
479 or $self->throw_exception( "No such relationship '$rel'" );
480
30236e47 481 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
164efde3 482 $attrs = { %{$rel_info->{attrs} || {}}, %$attrs };
30236e47 483
bc0c9800 484 $self->throw_exception( "Invalid query: @_" )
485 if (@_ > 1 && (@_ % 2 == 1));
30236e47 486 my $query = ((@_ > 1) ? {@_} : shift);
487
72c2540d 488 my $rsrc = $self->result_source;
d419ded6 489
490 # condition resolution may fail if an incomplete master-object prefetch
34b6b86f 491 # is encountered - that is ok during prefetch construction (not yet in_storage)
aa56106b 492 my ($cond, $is_crosstable) = try {
72c2540d 493 $rsrc->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel )
52b420dd 494 }
ed7ab0f4 495 catch {
f8193780 496 $self->throw_exception ($_) if $self->in_storage;
facd0e8e 497 UNRESOLVABLE_CONDITION; # RV, no return()
ed7ab0f4 498 };
d419ded6 499
aa56106b 500 # keep in mind that the following if() block is part of a do{} - no return()s!!!
03f6d1f7 501 if ($is_crosstable and ref $rel_info->{cond} eq 'CODE') {
aa56106b 502
503 # A WHOREIFFIC hack to reinvoke the entire condition resolution
504 # with the correct alias. Another way of doing this involves a
505 # lot of state passing around, and the @_ positions are already
506 # mapped out, making this crap a less icky option.
507 #
508 # The point of this exercise is to retain the spirit of the original
509 # $obj->search_related($rel) where the resulting rset will have the
510 # root alias as 'me', instead of $rel (as opposed to invoking
511 # $rs->search_related)
512
72c2540d 513 local $rsrc->{_relationships}{me} = $rsrc->{_relationships}{$rel}; # make the fake 'me' rel
514 my $obj_table_alias = lc($rsrc->source_name) . '__row';
93508f48 515 $obj_table_alias =~ s/\W+/_/g;
aa56106b 516
72c2540d 517 $rsrc->resultset->search(
aa56106b 518 $self->ident_condition($obj_table_alias),
519 { alias => $obj_table_alias },
520 )->search_related('me', $query, $attrs)
68f3b0dd 521 }
aa56106b 522 else {
523 # FIXME - this conditional doesn't seem correct - got to figure out
524 # at some point what it does. Also the entire UNRESOLVABLE_CONDITION
525 # business seems shady - we could simply not query *at all*
facd0e8e 526 if ($cond eq UNRESOLVABLE_CONDITION) {
72c2540d 527 my $reverse = $rsrc->reverse_relationship_info($rel);
aa56106b 528 foreach my $rev_rel (keys %$reverse) {
529 if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
0a03206a 530 weaken($attrs->{related_objects}{$rev_rel}[0] = $self);
aa56106b 531 } else {
0a03206a 532 weaken($attrs->{related_objects}{$rev_rel} = $self);
aa56106b 533 }
534 }
9aae3566 535 }
aa56106b 536 elsif (ref $cond eq 'ARRAY') {
7689b9e5 537 $cond = [ map {
538 if (ref $_ eq 'HASH') {
539 my $hash;
540 foreach my $key (keys %$_) {
541 my $newkey = $key !~ /\./ ? "me.$key" : $key;
542 $hash->{$newkey} = $_->{$key};
543 }
544 $hash;
545 } else {
546 $_;
370f2ba2 547 }
7689b9e5 548 } @$cond ];
aa56106b 549 }
550 elsif (ref $cond eq 'HASH') {
551 foreach my $key (grep { ! /\./ } keys %$cond) {
7689b9e5 552 $cond->{"me.$key"} = delete $cond->{$key};
370f2ba2 553 }
30236e47 554 }
a126983e 555
7689b9e5 556 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
72c2540d 557 $rsrc->related_source($rel)->resultset->search(
aa56106b 558 $query, $attrs
559 );
7689b9e5 560 }
30236e47 561 };
562}
563
8091aa91 564=head2 search_related
503536d5 565
dad42de6 566=over 4
567
568=item Arguments: $rel_name, $cond?, L<\%attrs?|DBIx::Class::ResultSet/ATTRIBUTES>
569
570=item Return Value: L<$resultset|DBIx::Class::ResultSet> (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context)
571
572=back
30236e47 573
574Run a search on a related resultset. The search will be restricted to the
dad42de6 575results represented by the L<DBIx::Class::ResultSet> it was called
576upon.
577
578See L<DBIx::Class::ResultSet/search_related> for more information.
503536d5 579
580=cut
581
55e2d745 582sub search_related {
ff7bb7a1 583 return shift->related_resultset(shift)->search(@_);
b52e9bf8 584}
585
5b89a768 586=head2 search_related_rs
587
fd323bf1 588This method works exactly the same as search_related, except that
48580715 589it guarantees a resultset, even in list context.
5b89a768 590
591=cut
592
593sub search_related_rs {
594 return shift->related_resultset(shift)->search_rs(@_);
595}
596
b52e9bf8 597=head2 count_related
598
dad42de6 599=over 4
600
601=item Arguments: $rel_name, $cond?, L<\%attrs?|DBIx::Class::ResultSet/ATTRIBUTES>
602
603=item Return Value: $count
b52e9bf8 604
dad42de6 605=back
606
607Returns the count of all the rows in the related resultset, restricted by the
608current result or where conditions.
30236e47 609
b52e9bf8 610=cut
611
612sub count_related {
4b8a53ea 613 shift->search_related(@_)->count;
55e2d745 614}
615
30236e47 616=head2 new_related
617
dad42de6 618=over 4
619
620=item Arguments: $rel_name, \%col_data
621
622=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
30236e47 623
dad42de6 624=back
625
626Create a new result object of the related foreign class. It will magically set
627any foreign key columns of the new object to the related primary key columns
628of the source object for you. The newly created result will not be saved into
629your storage until you call L<DBIx::Class::Row/insert> on it.
30236e47 630
631=cut
632
633sub new_related {
81e4dc3d 634 my ($self, $rel, $values) = @_;
78b948c3 635
636 # FIXME - this is a bad position for this (also an identical copy in
637 # set_from_related), but I have no saner way to hook, and I absolutely
638 # want this to throw at least for coderefs, instead of the "insert a NULL
639 # when it gets hard" insanity --ribasushi
640 #
641 # sanity check - currently throw when a complex coderef rel is encountered
642 # FIXME - should THROW MOAR!
643
644 if (ref $self) { # cdbi calls this as a class method, /me vomits
645
646 my $rsrc = $self->result_source;
3f8affda 647 my $rel_info = $rsrc->relationship_info($rel)
648 or $self->throw_exception( "No such relationship '$rel'" );
f8193780 649 my (undef, $crosstable, $nonequality_foreign_columns) = $rsrc->_resolve_condition (
3f8affda 650 $rel_info->{cond}, $rel, $self, $rel
78b948c3 651 );
652
1daf1363 653 $self->throw_exception("Relationship '$rel' does not resolve to a join-free condition fragment")
78b948c3 654 if $crosstable;
655
f8193780 656 if (
657 $nonequality_foreign_columns
658 and
659 my @unspecified_rel_condition_chunks = grep { ! exists $values->{$_} } @$nonequality_foreign_columns
660 ) {
78b948c3 661 $self->throw_exception(sprintf (
662 "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
663 $rel,
72c2540d 664 map { "'$_'" } @unspecified_rel_condition_chunks
78b948c3 665 ));
666 }
667 }
668
81e4dc3d 669 return $self->search_related($rel)->new_result($values);
30236e47 670}
671
8091aa91 672=head2 create_related
503536d5 673
dad42de6 674=over 4
30236e47 675
dad42de6 676=item Arguments: $rel_name, \%col_data
677
678=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
679
680=back
681
682 my $result = $obj->create_related($rel_name, \%col_data);
683
684Creates a new result object, similarly to new_related, and also inserts the
685result's data into your storage medium. See the distinction between C<create>
686and C<new> in L<DBIx::Class::ResultSet> for details.
503536d5 687
688=cut
689
55e2d745 690sub create_related {
3842b955 691 my $self = shift;
fea3d045 692 my $rel = shift;
78b948c3 693 my $obj = $self->new_related($rel, @_)->insert;
64acc2bc 694 delete $self->{related_resultsets}->{$rel};
695 return $obj;
55e2d745 696}
697
8091aa91 698=head2 find_related
503536d5 699
dad42de6 700=over 4
701
702=item Arguments: $rel_name, \%col_data | @pk_values, { key => $unique_constraint, L<%attrs|DBIx::Class::ResultSet/ATTRIBUTES> }?
703
704=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | undef
705
706=back
707
708 my $result = $obj->find_related($rel_name, \%col_data);
30236e47 709
710Attempt to find a related object using its primary key or unique constraints.
27f01d1f 711See L<DBIx::Class::ResultSet/find> for details.
503536d5 712
713=cut
714
1a14aa3f 715sub find_related {
4b8a53ea 716 #my ($self, $rel, @args) = @_;
717 return shift->search_related(shift)->find(@_);
1a14aa3f 718}
719
b3e1f1f5 720=head2 find_or_new_related
721
dad42de6 722=over 4
b3e1f1f5 723
dad42de6 724=item Arguments: $rel_name, \%col_data, { key => $unique_constraint, L<%attrs|DBIx::Class::ResultSet/ATTRIBUTES> }?
725
726=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
727
728=back
729
730Find a result object of a related class. See L<DBIx::Class::ResultSet/find_or_new>
731for details.
b3e1f1f5 732
733=cut
734
735sub find_or_new_related {
736 my $self = shift;
e60dc79f 737 my $obj = $self->find_related(@_);
738 return defined $obj ? $obj : $self->new_related(@_);
b3e1f1f5 739}
740
8091aa91 741=head2 find_or_create_related
503536d5 742
dad42de6 743=over 4
744
745=item Arguments: $rel_name, \%col_data, { key => $unique_constraint, L<%attrs|DBIx::Class::ResultSet/ATTRIBUTES> }?
746
747=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
748
749=back
30236e47 750
dad42de6 751Find or create a result object of a related class. See
b3e1f1f5 752L<DBIx::Class::ResultSet/find_or_create> for details.
503536d5 753
754=cut
755
55e2d745 756sub find_or_create_related {
757 my $self = shift;
9c2c91ea 758 my $obj = $self->find_related(@_);
759 return (defined($obj) ? $obj : $self->create_related(@_));
55e2d745 760}
761
045120e6 762=head2 update_or_create_related
763
dad42de6 764=over 4
765
766=item Arguments: $rel_name, \%col_data, { key => $unique_constraint, L<%attrs|DBIx::Class::ResultSet/ATTRIBUTES> }?
767
768=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
769
770=back
045120e6 771
dad42de6 772Update or create a result object of a related class. See
f7e1846f 773L<DBIx::Class::ResultSet/update_or_create> for details.
045120e6 774
775=cut
776
777sub update_or_create_related {
4b8a53ea 778 #my ($self, $rel, @args) = @_;
779 shift->related_resultset(shift)->update_or_create(@_);
045120e6 780}
781
8091aa91 782=head2 set_from_related
503536d5 783
dad42de6 784=over 4
785
786=item Arguments: $rel_name, L<$result|DBIx::Class::Manual::ResultClass>
787
788=item Return Value: not defined
789
790=back
791
30236e47 792 $book->set_from_related('author', $author_obj);
ac8e89d7 793 $book->author($author_obj); ## same thing
30236e47 794
795Set column values on the current object, using related values from the given
796related object. This is used to associate previously separate objects, for
797example, to set the correct author for a book, find the Author object, then
798call set_from_related on the book.
799
ac8e89d7 800This is called internally when you pass existing objects as values to
48580715 801L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to accessor.
ac8e89d7 802
27f01d1f 803The columns are only set in the local copy of the object, call L</update> to
804set them in the storage.
503536d5 805
806=cut
807
55e2d745 808sub set_from_related {
809 my ($self, $rel, $f_obj) = @_;
aa56106b 810
78b948c3 811 my $rsrc = $self->result_source;
812 my $rel_info = $rsrc->relationship_info($rel)
e705f529 813 or $self->throw_exception( "No such relationship '$rel'" );
aa56106b 814
2c037e6b 815 if (defined $f_obj) {
164efde3 816 my $f_class = $rel_info->{class};
e705f529 817 $self->throw_exception( "Object '$f_obj' isn't a ".$f_class )
6298a324 818 unless blessed $f_obj and $f_obj->isa($f_class);
2c037e6b 819 }
a126983e 820
a126983e 821
78b948c3 822 # FIXME - this is a bad position for this (also an identical copy in
823 # new_related), but I have no saner way to hook, and I absolutely
824 # want this to throw at least for coderefs, instead of the "insert a NULL
825 # when it gets hard" insanity --ribasushi
826 #
827 # sanity check - currently throw when a complex coderef rel is encountered
828 # FIXME - should THROW MOAR!
f8193780 829 my ($cond, $crosstable, $nonequality_foreign_columns) = $rsrc->_resolve_condition (
78b948c3 830 $rel_info->{cond}, $f_obj, $rel, $rel
831 );
1daf1363 832 $self->throw_exception("Relationship '$rel' does not resolve to a join-free condition fragment")
78b948c3 833 if $crosstable;
f8193780 834
78b948c3 835 $self->throw_exception(sprintf (
836 "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
837 $rel,
f8193780 838 map { "'$_'" } @$nonequality_foreign_columns
839 )) if $nonequality_foreign_columns;
aa56106b 840
841 $self->set_columns($cond);
a126983e 842
55e2d745 843 return 1;
844}
845
8091aa91 846=head2 update_from_related
503536d5 847
dad42de6 848=over 4
849
850=item Arguments: $rel_name, L<$result|DBIx::Class::Manual::ResultClass>
851
852=item Return Value: not defined
853
854=back
855
30236e47 856 $book->update_from_related('author', $author_obj);
857
27f01d1f 858The same as L</"set_from_related">, but the changes are immediately updated
859in storage.
503536d5 860
861=cut
862
55e2d745 863sub update_from_related {
864 my $self = shift;
865 $self->set_from_related(@_);
866 $self->update;
867}
868
8091aa91 869=head2 delete_related
503536d5 870
dad42de6 871=over 4
30236e47 872
dad42de6 873=item Arguments: $rel_name, $cond?, L<\%attrs?|DBIx::Class::ResultSet/ATTRIBUTES>
874
69bc5f2b 875=item Return Value: $underlying_storage_rv
dad42de6 876
877=back
878
879Delete any related row, subject to the given conditions. Internally, this
880calls:
881
882 $self->search_related(@_)->delete
883
884And returns the result of that.
503536d5 885
886=cut
887
55e2d745 888sub delete_related {
889 my $self = shift;
64acc2bc 890 my $obj = $self->search_related(@_)->delete;
891 delete $self->{related_resultsets}->{$_[0]};
892 return $obj;
55e2d745 893}
894
ec353f53 895=head2 add_to_$rel
896
dad42de6 897B<Currently only available for C<has_many>, C<many_to_many> and 'multi' type
ec353f53 898relationships.>
899
dad42de6 900=head3 has_many / multi
901
ec353f53 902=over 4
903
dad42de6 904=item Arguments: \%col_data
905
906=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
907
908=back
909
910Creates/inserts a new result object. Internally, this calls:
911
912 $self->create_related($rel, @_)
913
914And returns the result of that.
915
916=head3 many_to_many
917
918=over 4
919
920=item Arguments: (\%col_data | L<$result|DBIx::Class::Manual::ResultClass>), \%link_col_data?
921
922=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
ec353f53 923
924=back
925
926 my $role = $schema->resultset('Role')->find(1);
927 $actor->add_to_roles($role);
dad42de6 928 # creates a My::DBIC::Schema::ActorRoles linking table result object
ec353f53 929
930 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
dad42de6 931 # creates a new My::DBIC::Schema::Role result object and the linking table
ec353f53 932 # object with an extra column in the link
933
dad42de6 934Adds a linking table object. If the first argument is a hash reference, the
935related object is created first with the column values in the hash. If an object
936reference is given, just the linking table object is created. In either case,
937any additional column values for the linking table object can be specified in
938C<\%link_col_data>.
939
940See L<DBIx::Class::Relationship/many_to_many> for additional details.
ec353f53 941
942=head2 set_$rel
943
dad42de6 944B<Currently only available for C<many_to_many> relationships.>
ec353f53 945
946=over 4
947
dad42de6 948=item Arguments: (\@hashrefs_of_col_data | L<\@result_objs|DBIx::Class::Manual::ResultClass>), $link_vals?
949
950=item Return Value: not defined
ec353f53 951
952=back
953
954 my $actor = $schema->resultset('Actor')->find(1);
fd323bf1 955 my @roles = $schema->resultset('Role')->search({ role =>
debccec3 956 { '-in' => ['Fred', 'Barney'] } } );
ec353f53 957
4d3a827d 958 $actor->set_roles(\@roles);
959 # Replaces all of $actor's previous roles with the two named
ec353f53 960
ac36a402 961 $actor->set_roles(\@roles, { salary => 15_000_000 });
962 # Sets a column in the link table for all roles
963
964
4d3a827d 965Replace all the related objects with the given reference to a list of
966objects. This does a C<delete> B<on the link table resultset> to remove the
967association between the current object and all related objects, then calls
968C<add_to_$rel> repeatedly to link all the new objects.
bba68c67 969
970Note that this means that this method will B<not> delete any objects in the
971table on the right side of the relation, merely that it will delete the link
972between them.
ec353f53 973
4d3a827d 974Due to a mistake in the original implementation of this method, it will also
975accept a list of objects or hash references. This is B<deprecated> and will be
976removed in a future version.
977
ec353f53 978=head2 remove_from_$rel
979
dad42de6 980B<Currently only available for C<many_to_many> relationships.>
ec353f53 981
982=over 4
983
dad42de6 984=item Arguments: L<$result|DBIx::Class::Manual::ResultClass>
985
986=item Return Value: not defined
ec353f53 987
988=back
989
990 my $role = $schema->resultset('Role')->find(1);
991 $actor->remove_from_roles($role);
dad42de6 992 # removes $role's My::DBIC::Schema::ActorRoles linking table result object
ec353f53 993
994Removes the link between the current object and the related object. Note that
995the related object itself won't be deleted unless you call ->delete() on
996it. This method just removes the link between the two objects.
997
0c11ad0e 998=head1 AUTHOR AND CONTRIBUTORS
55e2d745 999
0c11ad0e 1000See L<AUTHOR|DBIx::Class/AUTHOR> and L<CONTRIBUTORS|DBIx::Class/CONTRIBUTORS> in DBIx::Class
55e2d745 1001
1002=head1 LICENSE
1003
1004You may distribute this code under the same terms as Perl itself.
1005
1006=cut
1007
4d87db01 10081;