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