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