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