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