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