A spec of what needs to happen to get complete custom relationships support
[dbsrgits/DBIx-Class.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)
52b420dd 266 my $cond = try {
267 $source->_resolve_condition( $rel_info->{cond}, $rel, $self )
268 }
ed7ab0f4 269 catch {
34b6b86f 270 if ($self->in_storage) {
ed7ab0f4 271 $self->throw_exception ($_);
34b6b86f 272 }
52b420dd 273
274 $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION; # RV
ed7ab0f4 275 };
d419ded6 276
68f3b0dd 277 if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
278 my $reverse = $source->reverse_relationship_info($rel);
279 foreach my $rev_rel (keys %$reverse) {
b82c8a28 280 if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
2c5c07ec 281 $attrs->{related_objects}{$rev_rel} = [ $self ];
6298a324 282 weaken $attrs->{related_object}{$rev_rel}[0];
2c5c07ec 283 } else {
284 $attrs->{related_objects}{$rev_rel} = $self;
6298a324 285 weaken $attrs->{related_object}{$rev_rel};
2c5c07ec 286 }
68f3b0dd 287 }
288 }
30236e47 289 if (ref $cond eq 'ARRAY') {
370f2ba2 290 $cond = [ map {
291 if (ref $_ eq 'HASH') {
292 my $hash;
293 foreach my $key (keys %$_) {
47752afe 294 my $newkey = $key !~ /\./ ? "me.$key" : $key;
370f2ba2 295 $hash->{$newkey} = $_->{$key};
296 }
297 $hash;
298 } else {
299 $_;
300 }
301 } @$cond ];
68f3b0dd 302 } elsif (ref $cond eq 'HASH') {
30236e47 303 foreach my $key (grep { ! /\./ } keys %$cond) {
304 $cond->{"me.$key"} = delete $cond->{$key};
305 }
306 }
307 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
bc0c9800 308 $self->result_source->related_source($rel)->resultset->search(
309 $query, $attrs
310 );
30236e47 311 };
312}
313
8091aa91 314=head2 search_related
503536d5 315
5b89a768 316 @objects = $rs->search_related('relname', $cond, $attrs);
317 $objects_rs = $rs->search_related('relname', $cond, $attrs);
30236e47 318
319Run a search on a related resultset. The search will be restricted to the
320item or items represented by the L<DBIx::Class::ResultSet> it was called
321upon. This method can be called on a ResultSet, a Row or a ResultSource class.
503536d5 322
323=cut
324
55e2d745 325sub search_related {
ff7bb7a1 326 return shift->related_resultset(shift)->search(@_);
b52e9bf8 327}
328
5b89a768 329=head2 search_related_rs
330
331 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
332
fd323bf1 333This method works exactly the same as search_related, except that
48580715 334it guarantees a resultset, even in list context.
5b89a768 335
336=cut
337
338sub search_related_rs {
339 return shift->related_resultset(shift)->search_rs(@_);
340}
341
b52e9bf8 342=head2 count_related
343
7be93b07 344 $obj->count_related('relname', $cond, $attrs);
b52e9bf8 345
bc0c9800 346Returns the count of all the items in the related resultset, restricted by the
347current item or where conditions. Can be called on a
27f01d1f 348L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
bc0c9800 349L<DBIx::Class::Manual::Glossary/"Row"> object.
30236e47 350
b52e9bf8 351=cut
352
353sub count_related {
354 my $self = shift;
355 return $self->search_related(@_)->count;
55e2d745 356}
357
30236e47 358=head2 new_related
359
360 my $new_obj = $obj->new_related('relname', \%col_data);
361
362Create a new item of the related foreign class. If called on a
fd323bf1 363L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically
364set any foreign key columns of the new object to the related primary
365key columns of the source object for you. The newly created item will
479b2a6a 366not be saved into your storage until you call L<DBIx::Class::Row/insert>
30236e47 367on it.
368
369=cut
370
371sub new_related {
372 my ($self, $rel, $values, $attrs) = @_;
373 return $self->search_related($rel)->new($values, $attrs);
374}
375
8091aa91 376=head2 create_related
503536d5 377
30236e47 378 my $new_obj = $obj->create_related('relname', \%col_data);
379
380Creates a new item, similarly to new_related, and also inserts the item's data
381into your storage medium. See the distinction between C<create> and C<new>
382in L<DBIx::Class::ResultSet> for details.
503536d5 383
384=cut
385
55e2d745 386sub create_related {
3842b955 387 my $self = shift;
fea3d045 388 my $rel = shift;
64acc2bc 389 my $obj = $self->search_related($rel)->create(@_);
390 delete $self->{related_resultsets}->{$rel};
391 return $obj;
55e2d745 392}
393
8091aa91 394=head2 find_related
503536d5 395
30236e47 396 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
397
398Attempt to find a related object using its primary key or unique constraints.
27f01d1f 399See L<DBIx::Class::ResultSet/find> for details.
503536d5 400
401=cut
402
1a14aa3f 403sub find_related {
404 my $self = shift;
405 my $rel = shift;
716b3d29 406 return $self->search_related($rel)->find(@_);
1a14aa3f 407}
408
b3e1f1f5 409=head2 find_or_new_related
410
411 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
412
413Find an item of a related class. If none exists, instantiate a new item of the
414related class. The object will not be saved into your storage until you call
415L<DBIx::Class::Row/insert> on it.
416
417=cut
418
419sub find_or_new_related {
420 my $self = shift;
e60dc79f 421 my $obj = $self->find_related(@_);
422 return defined $obj ? $obj : $self->new_related(@_);
b3e1f1f5 423}
424
8091aa91 425=head2 find_or_create_related
503536d5 426
30236e47 427 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
428
27f01d1f 429Find or create an item of a related class. See
b3e1f1f5 430L<DBIx::Class::ResultSet/find_or_create> for details.
503536d5 431
432=cut
433
55e2d745 434sub find_or_create_related {
435 my $self = shift;
9c2c91ea 436 my $obj = $self->find_related(@_);
437 return (defined($obj) ? $obj : $self->create_related(@_));
55e2d745 438}
439
045120e6 440=head2 update_or_create_related
441
442 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
443
444Update or create an item of a related class. See
f7e1846f 445L<DBIx::Class::ResultSet/update_or_create> for details.
045120e6 446
447=cut
448
449sub update_or_create_related {
450 my $self = shift;
451 my $rel = shift;
452 return $self->related_resultset($rel)->update_or_create(@_);
453}
454
8091aa91 455=head2 set_from_related
503536d5 456
30236e47 457 $book->set_from_related('author', $author_obj);
ac8e89d7 458 $book->author($author_obj); ## same thing
30236e47 459
460Set column values on the current object, using related values from the given
461related object. This is used to associate previously separate objects, for
462example, to set the correct author for a book, find the Author object, then
463call set_from_related on the book.
464
ac8e89d7 465This is called internally when you pass existing objects as values to
48580715 466L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to accessor.
ac8e89d7 467
27f01d1f 468The columns are only set in the local copy of the object, call L</update> to
469set them in the storage.
503536d5 470
471=cut
472
55e2d745 473sub set_from_related {
474 my ($self, $rel, $f_obj) = @_;
164efde3 475 my $rel_info = $self->relationship_info($rel);
476 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_info;
477 my $cond = $rel_info->{cond};
bc0c9800 478 $self->throw_exception(
479 "set_from_related can only handle a hash condition; the ".
480 "condition for $rel is of type ".
481 (ref $cond ? ref $cond : 'plain scalar')
482 ) unless ref $cond eq 'HASH';
2c037e6b 483 if (defined $f_obj) {
164efde3 484 my $f_class = $rel_info->{class};
2c037e6b 485 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
6298a324 486 unless blessed $f_obj and $f_obj->isa($f_class);
2c037e6b 487 }
fde6e28e 488 $self->set_columns(
6d0ee587 489 $self->result_source->_resolve_condition(
164efde3 490 $rel_info->{cond}, $f_obj, $rel));
55e2d745 491 return 1;
492}
493
8091aa91 494=head2 update_from_related
503536d5 495
30236e47 496 $book->update_from_related('author', $author_obj);
497
27f01d1f 498The same as L</"set_from_related">, but the changes are immediately updated
499in storage.
503536d5 500
501=cut
502
55e2d745 503sub update_from_related {
504 my $self = shift;
505 $self->set_from_related(@_);
506 $self->update;
507}
508
8091aa91 509=head2 delete_related
503536d5 510
30236e47 511 $obj->delete_related('relname', $cond, $attrs);
512
513Delete any related item subject to the given conditions.
503536d5 514
515=cut
516
55e2d745 517sub delete_related {
518 my $self = shift;
64acc2bc 519 my $obj = $self->search_related(@_)->delete;
520 delete $self->{related_resultsets}->{$_[0]};
521 return $obj;
55e2d745 522}
523
ec353f53 524=head2 add_to_$rel
525
526B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
527relationships.>
528
529=over 4
530
531=item Arguments: ($foreign_vals | $obj), $link_vals?
532
533=back
534
535 my $role = $schema->resultset('Role')->find(1);
536 $actor->add_to_roles($role);
537 # creates a My::DBIC::Schema::ActorRoles linking table row object
538
539 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
540 # creates a new My::DBIC::Schema::Role row object and the linking table
541 # object with an extra column in the link
542
543Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
544argument is a hash reference, the related object is created first with the
545column values in the hash. If an object reference is given, just the linking
546table object is created. In either case, any additional column values for the
547linking table object can be specified in C<$link_vals>.
548
549=head2 set_$rel
550
551B<Currently only available for C<many-to-many> relationships.>
552
553=over 4
554
ac36a402 555=item Arguments: (\@hashrefs | \@objs), $link_vals?
ec353f53 556
557=back
558
559 my $actor = $schema->resultset('Actor')->find(1);
fd323bf1 560 my @roles = $schema->resultset('Role')->search({ role =>
debccec3 561 { '-in' => ['Fred', 'Barney'] } } );
ec353f53 562
4d3a827d 563 $actor->set_roles(\@roles);
564 # Replaces all of $actor's previous roles with the two named
ec353f53 565
ac36a402 566 $actor->set_roles(\@roles, { salary => 15_000_000 });
567 # Sets a column in the link table for all roles
568
569
4d3a827d 570Replace all the related objects with the given reference to a list of
571objects. This does a C<delete> B<on the link table resultset> to remove the
572association between the current object and all related objects, then calls
573C<add_to_$rel> repeatedly to link all the new objects.
bba68c67 574
575Note that this means that this method will B<not> delete any objects in the
576table on the right side of the relation, merely that it will delete the link
577between them.
ec353f53 578
4d3a827d 579Due to a mistake in the original implementation of this method, it will also
580accept a list of objects or hash references. This is B<deprecated> and will be
581removed in a future version.
582
ec353f53 583=head2 remove_from_$rel
584
585B<Currently only available for C<many-to-many> relationships.>
586
587=over 4
588
589=item Arguments: $obj
590
591=back
592
593 my $role = $schema->resultset('Role')->find(1);
594 $actor->remove_from_roles($role);
595 # removes $role's My::DBIC::Schema::ActorRoles linking table row object
596
597Removes the link between the current object and the related object. Note that
598the related object itself won't be deleted unless you call ->delete() on
599it. This method just removes the link between the two objects.
600
55e2d745 601=head1 AUTHORS
602
daec44b8 603Matt S. Trout <mst@shadowcatsystems.co.uk>
55e2d745 604
605=head1 LICENSE
606
607You may distribute this code under the same terms as Perl itself.
608
609=cut
610
4d87db01 6111;