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