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