1 package DBIx::Class::Relationship::Base;
7 use base qw/DBIx::Class/;
11 DBIx::Class::Relationship::Base - Inter-table relationships
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>.
23 =head2 add_relationship
27 =item Arguments: 'relname', 'Foreign::Class', $cond, $attrs
31 __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs);
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.
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>
45 { 'foreign.author_id' => 'self.id' }
47 will result in the C<JOIN> clause
49 author me JOIN book book ON book.author_id = me.id
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"):
57 'foreign.publisher_id' => 'self.publisher_id',
58 'foreign.type_id' => 'self.type_id',
61 This will result in the C<JOIN> clause:
63 book me JOIN edition edition ON edition.publisher_id = me.publisher_id
64 AND edition.type_id = me.type_id
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.
71 L<standard ResultSet attributes|DBIx::Class::ResultSet/ATTRIBUTES>,
72 the following attributes are also valid:
78 Explicitly specifies the type of join to use in the relationship. Any SQL
79 join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
80 command immediately before C<JOIN>.
84 An arrayref containing a list of accessors in the foreign class to create in
85 the main class. If, for example, you do the following:
87 MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes',
89 proxy => [ qw/notes/ ],
92 Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do:
94 my $cd = MyDB::Schema::CD->find(1);
95 $cd->notes('Notes go here'); # set notes -- LinerNotes object is
96 # created if it doesn't exist
100 Specifies the type of accessor that should be created for the relationship.
101 Valid values are C<single> (for when there is only a single related object),
102 C<multi> (when there can be many), and C<filter> (for when there is a single
103 related object, but you also want the relationship accessor to double as
104 a column accessor). For C<multi> accessors, an add_to_* method is also
105 created, which calls C<create_related> for the relationship.
107 =item is_foreign_key_constraint
109 If you are using L<SQL::Translator> to create SQL for you and you find that it
110 is creating constraints where it shouldn't, or not creating them where it
111 should, set this attribute to a true or false value to override the detection
112 of when to create constraints.
114 =item on_delete / on_update
116 If you are using L<SQL::Translator> to create SQL for you, you can use these
117 attributes to explicitly set the desired C<ON DELETE> or C<ON UPDATE> constraint
118 type. If not supplied the SQLT parser will attempt to infer the constraint type by
119 interrogating the attributes of the B<opposite> relationship. For any 'multi'
120 relationship with C<< cascade_delete => 1 >>, the corresponding belongs_to
121 relationship will be created with an C<ON DELETE CASCADE> constraint. For any
122 relationship bearing C<< cascade_copy => 1 >> the resulting belongs_to constraint
123 will be C<ON UPDATE CASCADE>. If you wish to disable this autodetection, and just
124 use the RDBMS' default constraint type, pass C<< on_delete => undef >> or
125 C<< on_delete => '' >>, and the same for C<on_update> respectively.
129 Tells L<SQL::Translator> that the foreign key constraint it creates should be
130 deferrable. In other words, the user may request that the constraint be ignored
131 until the end of the transaction. Currently, only the PostgreSQL producer
132 actually supports this.
136 Tells L<SQL::Translator> to add an index for this constraint. Can also be
137 specified globally in the args to L<DBIx::Class::Schema/deploy> or
138 L<DBIx::Class::Schema/create_ddl_dir>. Default is on, set to 0 to disable.
142 =head2 register_relationship
146 =item Arguments: $relname, $rel_info
150 Registers a relationship on the class. This is called internally by
151 DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
155 sub register_relationship { }
157 =head2 related_resultset
161 =item Arguments: $relationship_name
163 =item Return Value: $related_resultset
167 $rs = $cd->related_resultset('artist');
169 Returns a L<DBIx::Class::ResultSet> for the relationship named
174 sub related_resultset {
176 $self->throw_exception("Can't call *_related as class methods")
179 my $rel_info = $self->relationship_info($rel);
180 $self->throw_exception( "No such relationship ${rel}" )
183 return $self->{related_resultsets}{$rel} ||= do {
184 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
185 $attrs = { %{$rel_info->{attrs} || {}}, %$attrs };
187 $self->throw_exception( "Invalid query: @_" )
188 if (@_ > 1 && (@_ % 2 == 1));
189 my $query = ((@_ > 1) ? {@_} : shift);
191 my $source = $self->result_source;
192 my $cond = $source->_resolve_condition(
193 $rel_info->{cond}, $rel, $self
195 if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
196 my $reverse = $source->reverse_relationship_info($rel);
197 foreach my $rev_rel (keys %$reverse) {
198 if ($reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
199 $attrs->{related_objects}{$rev_rel} = [ $self ];
200 Scalar::Util::weaken($attrs->{related_object}{$rev_rel}[0]);
202 $attrs->{related_objects}{$rev_rel} = $self;
203 Scalar::Util::weaken($attrs->{related_object}{$rev_rel});
207 if (ref $cond eq 'ARRAY') {
209 if (ref $_ eq 'HASH') {
211 foreach my $key (keys %$_) {
212 my $newkey = $key !~ /\./ ? "me.$key" : $key;
213 $hash->{$newkey} = $_->{$key};
220 } elsif (ref $cond eq 'HASH') {
221 foreach my $key (grep { ! /\./ } keys %$cond) {
222 $cond->{"me.$key"} = delete $cond->{$key};
225 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
226 $self->result_source->related_source($rel)->resultset->search(
232 =head2 search_related
234 @objects = $rs->search_related('relname', $cond, $attrs);
235 $objects_rs = $rs->search_related('relname', $cond, $attrs);
237 Run a search on a related resultset. The search will be restricted to the
238 item or items represented by the L<DBIx::Class::ResultSet> it was called
239 upon. This method can be called on a ResultSet, a Row or a ResultSource class.
244 return shift->related_resultset(shift)->search(@_);
247 =head2 search_related_rs
249 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
251 This method works exactly the same as search_related, except that
252 it guarantees a restultset, even in list context.
256 sub search_related_rs {
257 return shift->related_resultset(shift)->search_rs(@_);
262 $obj->count_related('relname', $cond, $attrs);
264 Returns the count of all the items in the related resultset, restricted by the
265 current item or where conditions. Can be called on a
266 L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
267 L<DBIx::Class::Manual::Glossary/"Row"> object.
273 return $self->search_related(@_)->count;
278 my $new_obj = $obj->new_related('relname', \%col_data);
280 Create a new item of the related foreign class. If called on a
281 L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically
282 set any foreign key columns of the new object to the related primary
283 key columns of the source object for you. The newly created item will
284 not be saved into your storage until you call L<DBIx::Class::Row/insert>
290 my ($self, $rel, $values, $attrs) = @_;
291 return $self->search_related($rel)->new($values, $attrs);
294 =head2 create_related
296 my $new_obj = $obj->create_related('relname', \%col_data);
298 Creates a new item, similarly to new_related, and also inserts the item's data
299 into your storage medium. See the distinction between C<create> and C<new>
300 in L<DBIx::Class::ResultSet> for details.
307 my $obj = $self->search_related($rel)->create(@_);
308 delete $self->{related_resultsets}->{$rel};
314 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
316 Attempt to find a related object using its primary key or unique constraints.
317 See L<DBIx::Class::ResultSet/find> for details.
324 return $self->search_related($rel)->find(@_);
327 =head2 find_or_new_related
329 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
331 Find an item of a related class. If none exists, instantiate a new item of the
332 related class. The object will not be saved into your storage until you call
333 L<DBIx::Class::Row/insert> on it.
337 sub find_or_new_related {
339 my $obj = $self->find_related(@_);
340 return defined $obj ? $obj : $self->new_related(@_);
343 =head2 find_or_create_related
345 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
347 Find or create an item of a related class. See
348 L<DBIx::Class::ResultSet/find_or_create> for details.
352 sub find_or_create_related {
354 my $obj = $self->find_related(@_);
355 return (defined($obj) ? $obj : $self->create_related(@_));
358 =head2 update_or_create_related
360 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
362 Update or create an item of a related class. See
363 L<DBIx::Class::ResultSet/update_or_create> for details.
367 sub update_or_create_related {
370 return $self->related_resultset($rel)->update_or_create(@_);
373 =head2 set_from_related
375 $book->set_from_related('author', $author_obj);
376 $book->author($author_obj); ## same thing
378 Set column values on the current object, using related values from the given
379 related object. This is used to associate previously separate objects, for
380 example, to set the correct author for a book, find the Author object, then
381 call set_from_related on the book.
383 This is called internally when you pass existing objects as values to
384 L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to acessor.
386 The columns are only set in the local copy of the object, call L</update> to
387 set them in the storage.
391 sub set_from_related {
392 my ($self, $rel, $f_obj) = @_;
393 my $rel_info = $self->relationship_info($rel);
394 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_info;
395 my $cond = $rel_info->{cond};
396 $self->throw_exception(
397 "set_from_related can only handle a hash condition; the ".
398 "condition for $rel is of type ".
399 (ref $cond ? ref $cond : 'plain scalar')
400 ) unless ref $cond eq 'HASH';
401 if (defined $f_obj) {
402 my $f_class = $rel_info->{class};
403 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
404 unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
407 $self->result_source->_resolve_condition(
408 $rel_info->{cond}, $f_obj, $rel));
412 =head2 update_from_related
414 $book->update_from_related('author', $author_obj);
416 The same as L</"set_from_related">, but the changes are immediately updated
421 sub update_from_related {
423 $self->set_from_related(@_);
427 =head2 delete_related
429 $obj->delete_related('relname', $cond, $attrs);
431 Delete any related item subject to the given conditions.
437 my $obj = $self->search_related(@_)->delete;
438 delete $self->{related_resultsets}->{$_[0]};
444 B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
449 =item Arguments: ($foreign_vals | $obj), $link_vals?
453 my $role = $schema->resultset('Role')->find(1);
454 $actor->add_to_roles($role);
455 # creates a My::DBIC::Schema::ActorRoles linking table row object
457 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
458 # creates a new My::DBIC::Schema::Role row object and the linking table
459 # object with an extra column in the link
461 Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
462 argument is a hash reference, the related object is created first with the
463 column values in the hash. If an object reference is given, just the linking
464 table object is created. In either case, any additional column values for the
465 linking table object can be specified in C<$link_vals>.
469 B<Currently only available for C<many-to-many> relationships.>
473 =item Arguments: (\@hashrefs | \@objs), $link_vals?
477 my $actor = $schema->resultset('Actor')->find(1);
478 my @roles = $schema->resultset('Role')->search({ role =>
479 { '-in' => ['Fred', 'Barney'] } } );
481 $actor->set_roles(\@roles);
482 # Replaces all of $actor's previous roles with the two named
484 $actor->set_roles(\@roles, { salary => 15_000_000 });
485 # Sets a column in the link table for all roles
488 Replace all the related objects with the given reference to a list of
489 objects. This does a C<delete> B<on the link table resultset> to remove the
490 association between the current object and all related objects, then calls
491 C<add_to_$rel> repeatedly to link all the new objects.
493 Note that this means that this method will B<not> delete any objects in the
494 table on the right side of the relation, merely that it will delete the link
497 Due to a mistake in the original implementation of this method, it will also
498 accept a list of objects or hash references. This is B<deprecated> and will be
499 removed in a future version.
501 =head2 remove_from_$rel
503 B<Currently only available for C<many-to-many> relationships.>
507 =item Arguments: $obj
511 my $role = $schema->resultset('Role')->find(1);
512 $actor->remove_from_roles($role);
513 # removes $role's My::DBIC::Schema::ActorRoles linking table row object
515 Removes the link between the current object and the related object. Note that
516 the related object itself won't be deleted unless you call ->delete() on
517 it. This method just removes the link between the two objects.
521 Matt S. Trout <mst@shadowcatsystems.co.uk>
525 You may distribute this code under the same terms as Perl itself.