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