Merge 'trunk' into 'pri_key_refactor'
[dbsrgits/DBIx-Class-Historic.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     my $cond = $source->_resolve_condition(
204       $rel_info->{cond}, $rel, $self
205     );
206     if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
207       my $reverse = $source->reverse_relationship_info($rel);
208       foreach my $rev_rel (keys %$reverse) {
209         if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
210           $attrs->{related_objects}{$rev_rel} = [ $self ];
211           Scalar::Util::weaken($attrs->{related_object}{$rev_rel}[0]);
212         } else {
213           $attrs->{related_objects}{$rev_rel} = $self;
214           Scalar::Util::weaken($attrs->{related_object}{$rev_rel});
215         }
216       }
217     }
218     if (ref $cond eq 'ARRAY') {
219       $cond = [ map {
220         if (ref $_ eq 'HASH') {
221           my $hash;
222           foreach my $key (keys %$_) {
223             my $newkey = $key !~ /\./ ? "me.$key" : $key;
224             $hash->{$newkey} = $_->{$key};
225           }
226           $hash;
227         } else {
228           $_;
229         }
230       } @$cond ];
231     } elsif (ref $cond eq 'HASH') {
232       foreach my $key (grep { ! /\./ } keys %$cond) {
233         $cond->{"me.$key"} = delete $cond->{$key};
234       }
235     }
236     $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
237     $self->result_source->related_source($rel)->resultset->search(
238       $query, $attrs
239     );
240   };
241 }
242
243 =head2 search_related
244
245   @objects = $rs->search_related('relname', $cond, $attrs);
246   $objects_rs = $rs->search_related('relname', $cond, $attrs);
247
248 Run a search on a related resultset. The search will be restricted to the
249 item or items represented by the L<DBIx::Class::ResultSet> it was called
250 upon. This method can be called on a ResultSet, a Row or a ResultSource class.
251
252 =cut
253
254 sub search_related {
255   return shift->related_resultset(shift)->search(@_);
256 }
257
258 =head2 search_related_rs
259
260   ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
261
262 This method works exactly the same as search_related, except that 
263 it guarantees a restultset, even in list context.
264
265 =cut
266
267 sub search_related_rs {
268   return shift->related_resultset(shift)->search_rs(@_);
269 }
270
271 =head2 count_related
272
273   $obj->count_related('relname', $cond, $attrs);
274
275 Returns the count of all the items in the related resultset, restricted by the
276 current item or where conditions. Can be called on a
277 L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
278 L<DBIx::Class::Manual::Glossary/"Row"> object.
279
280 =cut
281
282 sub count_related {
283   my $self = shift;
284   return $self->search_related(@_)->count;
285 }
286
287 =head2 new_related
288
289   my $new_obj = $obj->new_related('relname', \%col_data);
290
291 Create a new item of the related foreign class. If called on a
292 L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically 
293 set any foreign key columns of the new object to the related primary 
294 key columns of the source object for you.  The newly created item will 
295 not be saved into your storage until you call L<DBIx::Class::Row/insert>
296 on it.
297
298 =cut
299
300 sub new_related {
301   my ($self, $rel, $values, $attrs) = @_;
302   return $self->search_related($rel)->new($values, $attrs);
303 }
304
305 =head2 create_related
306
307   my $new_obj = $obj->create_related('relname', \%col_data);
308
309 Creates a new item, similarly to new_related, and also inserts the item's data
310 into your storage medium. See the distinction between C<create> and C<new>
311 in L<DBIx::Class::ResultSet> for details.
312
313 =cut
314
315 sub create_related {
316   my $self = shift;
317   my $rel = shift;
318   my $obj = $self->search_related($rel)->create(@_);
319   delete $self->{related_resultsets}->{$rel};
320   return $obj;
321 }
322
323 =head2 find_related
324
325   my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
326
327 Attempt to find a related object using its primary key or unique constraints.
328 See L<DBIx::Class::ResultSet/find> for details.
329
330 =cut
331
332 sub find_related {
333   my $self = shift;
334   my $rel = shift;
335   return $self->search_related($rel)->find(@_);
336 }
337
338 =head2 find_or_new_related
339
340   my $new_obj = $obj->find_or_new_related('relname', \%col_data);
341
342 Find an item of a related class. If none exists, instantiate a new item of the
343 related class. The object will not be saved into your storage until you call
344 L<DBIx::Class::Row/insert> on it.
345
346 =cut
347
348 sub find_or_new_related {
349   my $self = shift;
350   my $obj = $self->find_related(@_);
351   return defined $obj ? $obj : $self->new_related(@_);
352 }
353
354 =head2 find_or_create_related
355
356   my $new_obj = $obj->find_or_create_related('relname', \%col_data);
357
358 Find or create an item of a related class. See
359 L<DBIx::Class::ResultSet/find_or_create> for details.
360
361 =cut
362
363 sub find_or_create_related {
364   my $self = shift;
365   my $obj = $self->find_related(@_);
366   return (defined($obj) ? $obj : $self->create_related(@_));
367 }
368
369 =head2 update_or_create_related
370
371   my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
372
373 Update or create an item of a related class. See
374 L<DBIx::Class::ResultSet/update_or_create> for details.
375
376 =cut
377
378 sub update_or_create_related {
379   my $self = shift;
380   my $rel = shift;
381   return $self->related_resultset($rel)->update_or_create(@_);
382 }
383
384 =head2 set_from_related
385
386   $book->set_from_related('author', $author_obj);
387   $book->author($author_obj);                      ## same thing
388
389 Set column values on the current object, using related values from the given
390 related object. This is used to associate previously separate objects, for
391 example, to set the correct author for a book, find the Author object, then
392 call set_from_related on the book.
393
394 This is called internally when you pass existing objects as values to
395 L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to acessor.
396
397 The columns are only set in the local copy of the object, call L</update> to
398 set them in the storage.
399
400 =cut
401
402 sub set_from_related {
403   my ($self, $rel, $f_obj) = @_;
404   my $rel_info = $self->relationship_info($rel);
405   $self->throw_exception( "No such relationship ${rel}" ) unless $rel_info;
406   my $cond = $rel_info->{cond};
407   $self->throw_exception(
408     "set_from_related can only handle a hash condition; the ".
409     "condition for $rel is of type ".
410     (ref $cond ? ref $cond : 'plain scalar')
411   ) unless ref $cond eq 'HASH';
412   if (defined $f_obj) {
413     my $f_class = $rel_info->{class};
414     $self->throw_exception( "Object $f_obj isn't a ".$f_class )
415       unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
416   }
417   $self->set_columns(
418     $self->result_source->_resolve_condition(
419        $rel_info->{cond}, $f_obj, $rel));
420   return 1;
421 }
422
423 =head2 update_from_related
424
425   $book->update_from_related('author', $author_obj);
426
427 The same as L</"set_from_related">, but the changes are immediately updated
428 in storage.
429
430 =cut
431
432 sub update_from_related {
433   my $self = shift;
434   $self->set_from_related(@_);
435   $self->update;
436 }
437
438 =head2 delete_related
439
440   $obj->delete_related('relname', $cond, $attrs);
441
442 Delete any related item subject to the given conditions.
443
444 =cut
445
446 sub delete_related {
447   my $self = shift;
448   my $obj = $self->search_related(@_)->delete;
449   delete $self->{related_resultsets}->{$_[0]};
450   return $obj;
451 }
452
453 =head2 add_to_$rel
454
455 B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
456 relationships.>
457
458 =over 4
459
460 =item Arguments: ($foreign_vals | $obj), $link_vals?
461
462 =back
463
464   my $role = $schema->resultset('Role')->find(1);
465   $actor->add_to_roles($role);
466       # creates a My::DBIC::Schema::ActorRoles linking table row object
467
468   $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
469       # creates a new My::DBIC::Schema::Role row object and the linking table
470       # object with an extra column in the link
471
472 Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
473 argument is a hash reference, the related object is created first with the
474 column values in the hash. If an object reference is given, just the linking
475 table object is created. In either case, any additional column values for the
476 linking table object can be specified in C<$link_vals>.
477
478 =head2 set_$rel
479
480 B<Currently only available for C<many-to-many> relationships.>
481
482 =over 4
483
484 =item Arguments: (\@hashrefs | \@objs), $link_vals?
485
486 =back
487
488   my $actor = $schema->resultset('Actor')->find(1);
489   my @roles = $schema->resultset('Role')->search({ role => 
490      { '-in' => ['Fred', 'Barney'] } } );
491
492   $actor->set_roles(\@roles);
493      # Replaces all of $actor's previous roles with the two named
494
495   $actor->set_roles(\@roles, { salary => 15_000_000 });
496      # Sets a column in the link table for all roles
497
498
499 Replace all the related objects with the given reference to a list of
500 objects. This does a C<delete> B<on the link table resultset> to remove the
501 association between the current object and all related objects, then calls
502 C<add_to_$rel> repeatedly to link all the new objects.
503
504 Note that this means that this method will B<not> delete any objects in the
505 table on the right side of the relation, merely that it will delete the link
506 between them.
507
508 Due to a mistake in the original implementation of this method, it will also
509 accept a list of objects or hash references. This is B<deprecated> and will be
510 removed in a future version.
511
512 =head2 remove_from_$rel
513
514 B<Currently only available for C<many-to-many> relationships.>
515
516 =over 4
517
518 =item Arguments: $obj
519
520 =back
521
522   my $role = $schema->resultset('Role')->find(1);
523   $actor->remove_from_roles($role);
524       # removes $role's My::DBIC::Schema::ActorRoles linking table row object
525
526 Removes the link between the current object and the related object. Note that
527 the related object itself won't be deleted unless you call ->delete() on
528 it. This method just removes the link between the two objects.
529
530 =head1 AUTHORS
531
532 Matt S. Trout <mst@shadowcatsystems.co.uk>
533
534 =head1 LICENSE
535
536 You may distribute this code under the same terms as Perl itself.
537
538 =cut
539
540 1;