Most of the code reviewed... Missing ResultSet->populate, ResultSet->find, Row->copy...
[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;
fd323bf1 10use namespace::clean;
55e2d745 11
75d07914 12=head1 NAME
55e2d745 13
8918977e 14DBIx::Class::Relationship::Base - Inter-table relationships
55e2d745 15
16=head1 SYNOPSIS
17
18=head1 DESCRIPTION
19
30236e47 20This class provides methods to describe the relationships between the
21tables in your database model. These are the "bare bones" relationships
75d07914 22methods, for predefined ones, look in L<DBIx::Class::Relationship>.
55e2d745 23
24=head1 METHODS
25
8091aa91 26=head2 add_relationship
503536d5 27
27f01d1f 28=over 4
29
ebc77b53 30=item Arguments: 'relname', 'Foreign::Class', $cond, $attrs
27f01d1f 31
32=back
30236e47 33
503536d5 34 __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs);
35
406734bb 36=head3 condition
37
5271499d 38The condition needs to be an L<SQL::Abstract>-style representation of the
39join between the tables. When resolving the condition for use in a C<JOIN>,
40keys using the pseudo-table C<foreign> are resolved to mean "the Table on the
41other side of the relationship", and values using the pseudo-table C<self>
30236e47 42are resolved to mean "the Table this class is representing". Other
43restrictions, such as by value, sub-select and other tables, may also be
5271499d 44used. Please check your database for C<JOIN> parameter support.
30236e47 45
5271499d 46For example, if you're creating a relationship from C<Author> to C<Book>, where
47the C<Book> table has a column C<author_id> containing the ID of the C<Author>
48row:
503536d5 49
30236e47 50 { 'foreign.author_id' => 'self.id' }
503536d5 51
5271499d 52will result in the C<JOIN> clause
503536d5 53
5271499d 54 author me JOIN book book ON book.author_id = me.id
503536d5 55
5271499d 56For multi-column foreign keys, you will need to specify a C<foreign>-to-C<self>
57mapping for each column in the key. For example, if you're creating a
58relationship from C<Book> to C<Edition>, where the C<Edition> table refers to a
59publisher and a type (e.g. "paperback"):
60
61 {
781102cd 62 'foreign.publisher_id' => 'self.publisher_id',
5271499d 63 'foreign.type_id' => 'self.type_id',
64 }
65
66This will result in the C<JOIN> clause:
67
68 book me JOIN edition edition ON edition.publisher_id = me.publisher_id
69 AND edition.type_id = me.type_id
70
71Each key-value pair provided in a hashref will be used as C<AND>ed conditions.
72To add an C<OR>ed condition, use an arrayref of hashrefs. See the
73L<SQL::Abstract> documentation for more details.
8091aa91 74
406734bb 75=head3 attributes
76
77The L<standard ResultSet attributes|DBIx::Class::ResultSet/ATTRIBUTES> may
78be used as relationship attributes. In particular, the 'where' attribute is
79useful for filtering relationships:
80
81 __PACKAGE__->has_many( 'valid_users', 'MyApp::Schema::User',
82 { 'foreign.user_id' => 'self.user_id' },
83 { where => { valid => 1 } }
84 );
85
86The following attributes are also valid:
8091aa91 87
88=over 4
89
90=item join_type
91
92Explicitly specifies the type of join to use in the relationship. Any SQL
93join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
94command immediately before C<JOIN>.
95
97c96475 96=item proxy =E<gt> $column | \@columns | \%column
97
98=over 4
99
100=item \@columns
8091aa91 101
30236e47 102An arrayref containing a list of accessors in the foreign class to create in
8091aa91 103the main class. If, for example, you do the following:
d4daee7b 104
27f01d1f 105 MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes',
106 undef, {
107 proxy => [ qw/notes/ ],
108 });
d4daee7b 109
30236e47 110Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do:
8091aa91 111
30236e47 112 my $cd = MyDB::Schema::CD->find(1);
113 $cd->notes('Notes go here'); # set notes -- LinerNotes object is
114 # created if it doesn't exist
d4daee7b 115
97c96475 116=item \%column
117
118A hashref where each key is the accessor you want installed in the main class,
119and its value is the name of the original in the fireign class.
120
121 MyDB::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', {
122 proxy => { cd_title => 'title' },
123 });
124
125This will create an accessor named C<cd_title> on the C<$track> row object.
126
127=back
128
129NOTE: you can pass a nested struct too, for example:
130
131 MyDB::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', {
132 proxy => [ 'year', { cd_title => 'title' } ],
133 });
134
8091aa91 135=item accessor
136
137Specifies the type of accessor that should be created for the relationship.
138Valid values are C<single> (for when there is only a single related object),
139C<multi> (when there can be many), and C<filter> (for when there is a single
140related object, but you also want the relationship accessor to double as
141a column accessor). For C<multi> accessors, an add_to_* method is also
142created, which calls C<create_related> for the relationship.
143
3d618782 144=item is_foreign_key_constraint
145
146If you are using L<SQL::Translator> to create SQL for you and you find that it
fd323bf1 147is creating constraints where it shouldn't, or not creating them where it
3d618782 148should, set this attribute to a true or false value to override the detection
149of when to create constraints.
150
5f7ac523 151=item cascade_copy
152
153If C<cascade_copy> is true on a C<has_many> relationship for an
154object, then when you copy the object all the related objects will
fd323bf1 155be copied too. To turn this behaviour off, pass C<< cascade_copy => 0 >>
156in the C<$attr> hashref.
b7bbc39f 157
158The behaviour defaults to C<< cascade_copy => 1 >> for C<has_many>
159relationships.
5f7ac523 160
161=item cascade_delete
162
b7bbc39f 163By default, DBIx::Class cascades deletes across C<has_many>,
164C<has_one> and C<might_have> relationships. You can disable this
fd323bf1 165behaviour on a per-relationship basis by supplying
b7bbc39f 166C<< cascade_delete => 0 >> in the relationship attributes.
5f7ac523 167
168The cascaded operations are performed after the requested delete,
169so if your database has a constraint on the relationship, it will
170have deleted/updated the related records or raised an exception
171before DBIx::Class gets to perform the cascaded operation.
172
173=item cascade_update
174
b7bbc39f 175By default, DBIx::Class cascades updates across C<has_one> and
5f7ac523 176C<might_have> relationships. You can disable this behaviour on a
b7bbc39f 177per-relationship basis by supplying C<< cascade_update => 0 >> in
178the relationship attributes.
5f7ac523 179
cee0c9b1 180This is not a RDMS style cascade update - it purely means that when
181an object has update called on it, all the related objects also
182have update called. It will not change foreign keys automatically -
183you must arrange to do this yourself.
5f7ac523 184
e377d723 185=item on_delete / on_update
186
187If you are using L<SQL::Translator> to create SQL for you, you can use these
fd323bf1 188attributes to explicitly set the desired C<ON DELETE> or C<ON UPDATE> constraint
189type. If not supplied the SQLT parser will attempt to infer the constraint type by
e377d723 190interrogating the attributes of the B<opposite> relationship. For any 'multi'
fd323bf1 191relationship with C<< cascade_delete => 1 >>, the corresponding belongs_to
192relationship will be created with an C<ON DELETE CASCADE> constraint. For any
e377d723 193relationship bearing C<< cascade_copy => 1 >> the resulting belongs_to constraint
194will be C<ON UPDATE CASCADE>. If you wish to disable this autodetection, and just
fd323bf1 195use the RDBMS' default constraint type, pass C<< on_delete => undef >> or
e377d723 196C<< on_delete => '' >>, and the same for C<on_update> respectively.
197
13de943d 198=item is_deferrable
199
200Tells L<SQL::Translator> that the foreign key constraint it creates should be
201deferrable. In other words, the user may request that the constraint be ignored
202until the end of the transaction. Currently, only the PostgreSQL producer
203actually supports this.
204
2581038c 205=item add_fk_index
206
207Tells L<SQL::Translator> to add an index for this constraint. Can also be
208specified globally in the args to L<DBIx::Class::Schema/deploy> or
209L<DBIx::Class::Schema/create_ddl_dir>. Default is on, set to 0 to disable.
210
8091aa91 211=back
212
87c4e602 213=head2 register_relationship
214
27f01d1f 215=over 4
216
ebc77b53 217=item Arguments: $relname, $rel_info
27f01d1f 218
219=back
71e65b39 220
30236e47 221Registers a relationship on the class. This is called internally by
71f9df37 222DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
71e65b39 223
55e2d745 224=cut
225
71e65b39 226sub register_relationship { }
227
27f01d1f 228=head2 related_resultset
229
230=over 4
231
ebc77b53 232=item Arguments: $relationship_name
27f01d1f 233
d601dc88 234=item Return Value: $related_resultset
27f01d1f 235
236=back
30236e47 237
27f01d1f 238 $rs = $cd->related_resultset('artist');
30236e47 239
27f01d1f 240Returns a L<DBIx::Class::ResultSet> for the relationship named
241$relationship_name.
30236e47 242
243=cut
244
245sub related_resultset {
246 my $self = shift;
bc0c9800 247 $self->throw_exception("Can't call *_related as class methods")
248 unless ref $self;
30236e47 249 my $rel = shift;
164efde3 250 my $rel_info = $self->relationship_info($rel);
bc0c9800 251 $self->throw_exception( "No such relationship ${rel}" )
164efde3 252 unless $rel_info;
d4daee7b 253
30236e47 254 return $self->{related_resultsets}{$rel} ||= do {
255 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
164efde3 256 $attrs = { %{$rel_info->{attrs} || {}}, %$attrs };
30236e47 257
bc0c9800 258 $self->throw_exception( "Invalid query: @_" )
259 if (@_ > 1 && (@_ % 2 == 1));
30236e47 260 my $query = ((@_ > 1) ? {@_} : shift);
261
68f3b0dd 262 my $source = $self->result_source;
d419ded6 263
264 # condition resolution may fail if an incomplete master-object prefetch
34b6b86f 265 # is encountered - that is ok during prefetch construction (not yet in_storage)
a126983e 266
267 # if $rel_info->{cond} is a CODE, we might need to join from the
268 # current resultsource instead of just querying the target
269 # resultsource, in that case, the condition might provide an
270 # additional condition in order to avoid an unecessary join if
271 # that is at all possible.
272 my ($cond, $cond2) = try {
52b420dd 273 $source->_resolve_condition( $rel_info->{cond}, $rel, $self )
274 }
ed7ab0f4 275 catch {
34b6b86f 276 if ($self->in_storage) {
ed7ab0f4 277 $self->throw_exception ($_);
34b6b86f 278 }
52b420dd 279
280 $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION; # RV
ed7ab0f4 281 };
d419ded6 282
68f3b0dd 283 if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
284 my $reverse = $source->reverse_relationship_info($rel);
285 foreach my $rev_rel (keys %$reverse) {
b82c8a28 286 if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
2c5c07ec 287 $attrs->{related_objects}{$rev_rel} = [ $self ];
6298a324 288 weaken $attrs->{related_object}{$rev_rel}[0];
2c5c07ec 289 } else {
290 $attrs->{related_objects}{$rev_rel} = $self;
6298a324 291 weaken $attrs->{related_object}{$rev_rel};
2c5c07ec 292 }
68f3b0dd 293 }
294 }
30236e47 295 if (ref $cond eq 'ARRAY') {
370f2ba2 296 $cond = [ map {
297 if (ref $_ eq 'HASH') {
298 my $hash;
299 foreach my $key (keys %$_) {
47752afe 300 my $newkey = $key !~ /\./ ? "me.$key" : $key;
370f2ba2 301 $hash->{$newkey} = $_->{$key};
302 }
303 $hash;
304 } else {
305 $_;
306 }
307 } @$cond ];
68f3b0dd 308 } elsif (ref $cond eq 'HASH') {
a126983e 309
310 # this is where we're going to check if we have an extended
311 # rel. In that case, we need to: 1) If there's a second
312 # condition, we use that instead. 2) If there is only one
313 # condition, we need to join the current resultsource and have
314 # additional conditions.
315 if (ref $rel_info->{cond} eq 'CODE') {
316 # this is an extended relationship.
317 if ($cond2) {
318 $cond = $cond2;
319 } else {
320 if (exists $attrs->{join} && $attrs->{join}) {
321 # it's a bit hard to find out what to do here.
322 $self->throw_exception('Extended relationship '.$rel.' with additional join not supported');
323 } else {
324 $attrs->{join} = $rel;
325 }
326 }
327 } else {
328 foreach my $key (grep { ! /\./ } keys %$cond) {
329 $cond->{"me.$key"} = delete $cond->{$key};
330 }
30236e47 331 }
332 }
a126983e 333
30236e47 334 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
bc0c9800 335 $self->result_source->related_source($rel)->resultset->search(
336 $query, $attrs
337 );
30236e47 338 };
339}
340
8091aa91 341=head2 search_related
503536d5 342
5b89a768 343 @objects = $rs->search_related('relname', $cond, $attrs);
344 $objects_rs = $rs->search_related('relname', $cond, $attrs);
30236e47 345
346Run a search on a related resultset. The search will be restricted to the
347item or items represented by the L<DBIx::Class::ResultSet> it was called
348upon. This method can be called on a ResultSet, a Row or a ResultSource class.
503536d5 349
350=cut
351
55e2d745 352sub search_related {
ff7bb7a1 353 return shift->related_resultset(shift)->search(@_);
b52e9bf8 354}
355
5b89a768 356=head2 search_related_rs
357
358 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
359
fd323bf1 360This method works exactly the same as search_related, except that
48580715 361it guarantees a resultset, even in list context.
5b89a768 362
363=cut
364
365sub search_related_rs {
366 return shift->related_resultset(shift)->search_rs(@_);
367}
368
b52e9bf8 369=head2 count_related
370
7be93b07 371 $obj->count_related('relname', $cond, $attrs);
b52e9bf8 372
bc0c9800 373Returns the count of all the items in the related resultset, restricted by the
374current item or where conditions. Can be called on a
27f01d1f 375L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
bc0c9800 376L<DBIx::Class::Manual::Glossary/"Row"> object.
30236e47 377
b52e9bf8 378=cut
379
380sub count_related {
381 my $self = shift;
382 return $self->search_related(@_)->count;
55e2d745 383}
384
30236e47 385=head2 new_related
386
387 my $new_obj = $obj->new_related('relname', \%col_data);
388
389Create a new item of the related foreign class. If called on a
fd323bf1 390L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically
391set any foreign key columns of the new object to the related primary
392key columns of the source object for you. The newly created item will
479b2a6a 393not be saved into your storage until you call L<DBIx::Class::Row/insert>
30236e47 394on it.
395
396=cut
397
398sub new_related {
399 my ($self, $rel, $values, $attrs) = @_;
400 return $self->search_related($rel)->new($values, $attrs);
401}
402
8091aa91 403=head2 create_related
503536d5 404
30236e47 405 my $new_obj = $obj->create_related('relname', \%col_data);
406
407Creates a new item, similarly to new_related, and also inserts the item's data
408into your storage medium. See the distinction between C<create> and C<new>
409in L<DBIx::Class::ResultSet> for details.
503536d5 410
411=cut
412
55e2d745 413sub create_related {
3842b955 414 my $self = shift;
fea3d045 415 my $rel = shift;
64acc2bc 416 my $obj = $self->search_related($rel)->create(@_);
417 delete $self->{related_resultsets}->{$rel};
418 return $obj;
55e2d745 419}
420
8091aa91 421=head2 find_related
503536d5 422
30236e47 423 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
424
425Attempt to find a related object using its primary key or unique constraints.
27f01d1f 426See L<DBIx::Class::ResultSet/find> for details.
503536d5 427
428=cut
429
1a14aa3f 430sub find_related {
431 my $self = shift;
432 my $rel = shift;
716b3d29 433 return $self->search_related($rel)->find(@_);
1a14aa3f 434}
435
b3e1f1f5 436=head2 find_or_new_related
437
438 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
439
440Find an item of a related class. If none exists, instantiate a new item of the
441related class. The object will not be saved into your storage until you call
442L<DBIx::Class::Row/insert> on it.
443
444=cut
445
446sub find_or_new_related {
447 my $self = shift;
e60dc79f 448 my $obj = $self->find_related(@_);
449 return defined $obj ? $obj : $self->new_related(@_);
b3e1f1f5 450}
451
8091aa91 452=head2 find_or_create_related
503536d5 453
30236e47 454 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
455
27f01d1f 456Find or create an item of a related class. See
b3e1f1f5 457L<DBIx::Class::ResultSet/find_or_create> for details.
503536d5 458
459=cut
460
55e2d745 461sub find_or_create_related {
462 my $self = shift;
9c2c91ea 463 my $obj = $self->find_related(@_);
464 return (defined($obj) ? $obj : $self->create_related(@_));
55e2d745 465}
466
045120e6 467=head2 update_or_create_related
468
469 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
470
471Update or create an item of a related class. See
f7e1846f 472L<DBIx::Class::ResultSet/update_or_create> for details.
045120e6 473
474=cut
475
476sub update_or_create_related {
477 my $self = shift;
478 my $rel = shift;
479 return $self->related_resultset($rel)->update_or_create(@_);
480}
481
8091aa91 482=head2 set_from_related
503536d5 483
30236e47 484 $book->set_from_related('author', $author_obj);
ac8e89d7 485 $book->author($author_obj); ## same thing
30236e47 486
487Set column values on the current object, using related values from the given
488related object. This is used to associate previously separate objects, for
489example, to set the correct author for a book, find the Author object, then
490call set_from_related on the book.
491
ac8e89d7 492This is called internally when you pass existing objects as values to
48580715 493L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to accessor.
ac8e89d7 494
27f01d1f 495The columns are only set in the local copy of the object, call L</update> to
496set them in the storage.
503536d5 497
498=cut
499
55e2d745 500sub set_from_related {
501 my ($self, $rel, $f_obj) = @_;
164efde3 502 my $rel_info = $self->relationship_info($rel);
503 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_info;
504 my $cond = $rel_info->{cond};
bc0c9800 505 $self->throw_exception(
506 "set_from_related can only handle a hash condition; the ".
507 "condition for $rel is of type ".
508 (ref $cond ? ref $cond : 'plain scalar')
509 ) unless ref $cond eq 'HASH';
2c037e6b 510 if (defined $f_obj) {
164efde3 511 my $f_class = $rel_info->{class};
2c037e6b 512 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
6298a324 513 unless blessed $f_obj and $f_obj->isa($f_class);
2c037e6b 514 }
a126983e 515
516 # _resolve_condition might return two hashrefs, specially in the
517 # current case, since we know $f_object is an object.
518 my ($condref1, $condref2) = $self->result_source->_resolve_condition
519 ($rel_info->{cond}, $f_obj, $rel);
520
521 # if we get two condrefs, we need to use the second, otherwise we
522 # use the first.
523 $self->set_columns($condref2 ? $condref2 : $condref1);
524
55e2d745 525 return 1;
526}
527
8091aa91 528=head2 update_from_related
503536d5 529
30236e47 530 $book->update_from_related('author', $author_obj);
531
27f01d1f 532The same as L</"set_from_related">, but the changes are immediately updated
533in storage.
503536d5 534
535=cut
536
55e2d745 537sub update_from_related {
538 my $self = shift;
539 $self->set_from_related(@_);
540 $self->update;
541}
542
8091aa91 543=head2 delete_related
503536d5 544
30236e47 545 $obj->delete_related('relname', $cond, $attrs);
546
547Delete any related item subject to the given conditions.
503536d5 548
549=cut
550
55e2d745 551sub delete_related {
552 my $self = shift;
64acc2bc 553 my $obj = $self->search_related(@_)->delete;
554 delete $self->{related_resultsets}->{$_[0]};
555 return $obj;
55e2d745 556}
557
ec353f53 558=head2 add_to_$rel
559
560B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
561relationships.>
562
563=over 4
564
565=item Arguments: ($foreign_vals | $obj), $link_vals?
566
567=back
568
569 my $role = $schema->resultset('Role')->find(1);
570 $actor->add_to_roles($role);
571 # creates a My::DBIC::Schema::ActorRoles linking table row object
572
573 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
574 # creates a new My::DBIC::Schema::Role row object and the linking table
575 # object with an extra column in the link
576
577Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
578argument is a hash reference, the related object is created first with the
579column values in the hash. If an object reference is given, just the linking
580table object is created. In either case, any additional column values for the
581linking table object can be specified in C<$link_vals>.
582
583=head2 set_$rel
584
585B<Currently only available for C<many-to-many> relationships.>
586
587=over 4
588
ac36a402 589=item Arguments: (\@hashrefs | \@objs), $link_vals?
ec353f53 590
591=back
592
593 my $actor = $schema->resultset('Actor')->find(1);
fd323bf1 594 my @roles = $schema->resultset('Role')->search({ role =>
debccec3 595 { '-in' => ['Fred', 'Barney'] } } );
ec353f53 596
4d3a827d 597 $actor->set_roles(\@roles);
598 # Replaces all of $actor's previous roles with the two named
ec353f53 599
ac36a402 600 $actor->set_roles(\@roles, { salary => 15_000_000 });
601 # Sets a column in the link table for all roles
602
603
4d3a827d 604Replace all the related objects with the given reference to a list of
605objects. This does a C<delete> B<on the link table resultset> to remove the
606association between the current object and all related objects, then calls
607C<add_to_$rel> repeatedly to link all the new objects.
bba68c67 608
609Note that this means that this method will B<not> delete any objects in the
610table on the right side of the relation, merely that it will delete the link
611between them.
ec353f53 612
4d3a827d 613Due to a mistake in the original implementation of this method, it will also
614accept a list of objects or hash references. This is B<deprecated> and will be
615removed in a future version.
616
ec353f53 617=head2 remove_from_$rel
618
619B<Currently only available for C<many-to-many> relationships.>
620
621=over 4
622
623=item Arguments: $obj
624
625=back
626
627 my $role = $schema->resultset('Role')->find(1);
628 $actor->remove_from_roles($role);
629 # removes $role's My::DBIC::Schema::ActorRoles linking table row object
630
631Removes the link between the current object and the related object. Note that
632the related object itself won't be deleted unless you call ->delete() on
633it. This method just removes the link between the two objects.
634
55e2d745 635=head1 AUTHORS
636
daec44b8 637Matt S. Trout <mst@shadowcatsystems.co.uk>
55e2d745 638
639=head1 LICENSE
640
641You may distribute this code under the same terms as Perl itself.
642
643=cut
644
4d87db01 6451;