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