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.
70 In addition to standard result set attributes, the following attributes are also valid:
76 Explicitly specifies the type of join to use in the relationship. Any SQL
77 join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
78 command immediately before C<JOIN>.
82 An arrayref containing a list of accessors in the foreign class to create in
83 the main class. If, for example, you do the following:
85 MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes',
87 proxy => [ qw/notes/ ],
90 Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do:
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
98 Specifies the type of accessor that should be created for the relationship.
99 Valid values are C<single> (for when there is only a single related object),
100 C<multi> (when there can be many), and C<filter> (for when there is a single
101 related object, but you also want the relationship accessor to double as
102 a column accessor). For C<multi> accessors, an add_to_* method is also
103 created, which calls C<create_related> for the relationship.
105 =item is_foreign_key_constraint
107 If you are using L<SQL::Translator> to create SQL for you and you find that it
108 is creating constraints where it shouldn't, or not creating them where it
109 should, set this attribute to a true or false value to override the detection
110 of when to create constraints.
114 =head2 register_relationship
118 =item Arguments: $relname, $rel_info
122 Registers a relationship on the class. This is called internally by
123 DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
127 sub register_relationship { }
129 =head2 related_resultset
133 =item Arguments: $relationship_name
135 =item Return Value: $related_resultset
139 $rs = $cd->related_resultset('artist');
141 Returns a L<DBIx::Class::ResultSet> for the relationship named
146 sub related_resultset {
148 $self->throw_exception("Can't call *_related as class methods")
151 my $rel_obj = $self->relationship_info($rel);
152 $self->throw_exception( "No such relationship ${rel}" )
155 return $self->{related_resultsets}{$rel} ||= do {
156 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
157 $attrs = { %{$rel_obj->{attrs} || {}}, %$attrs };
159 $self->throw_exception( "Invalid query: @_" )
160 if (@_ > 1 && (@_ % 2 == 1));
161 my $query = ((@_ > 1) ? {@_} : shift);
163 my $cond = $self->result_source->resolve_condition(
164 $rel_obj->{cond}, $rel, $self
166 if (ref $cond eq 'ARRAY') {
167 $cond = [ map { my $hash;
168 foreach my $key (keys %$_) {
169 my $newkey = $key =~ /\./ ? "me.$key" : $key;
170 $hash->{$newkey} = $_->{$key};
173 foreach my $key (grep { ! /\./ } keys %$cond) {
174 $cond->{"me.$key"} = delete $cond->{$key};
177 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
178 $self->result_source->related_source($rel)->resultset->search(
184 =head2 search_related
186 @objects = $rs->search_related('relname', $cond, $attrs);
187 $objects_rs = $rs->search_related('relname', $cond, $attrs);
189 Run a search on a related resultset. The search will be restricted to the
190 item or items represented by the L<DBIx::Class::ResultSet> it was called
191 upon. This method can be called on a ResultSet, a Row or a ResultSource class.
196 return shift->related_resultset(shift)->search(@_);
199 =head2 search_related_rs
201 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
203 This method works exactly the same as search_related, except that
204 it garauntees a restultset, even in list context.
208 sub search_related_rs {
209 return shift->related_resultset(shift)->search_rs(@_);
214 $obj->count_related('relname', $cond, $attrs);
216 Returns the count of all the items in the related resultset, restricted by the
217 current item or where conditions. Can be called on a
218 L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
219 L<DBIx::Class::Manual::Glossary/"Row"> object.
225 return $self->search_related(@_)->count;
230 my $new_obj = $obj->new_related('relname', \%col_data);
232 Create a new item of the related foreign class. If called on a
233 L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically
234 set any foreign key columns of the new object to the related primary
235 key columns of the source object for you. The newly created item will
236 not be saved into your storage until you call L<DBIx::Class::Row/insert>
242 my ($self, $rel, $values, $attrs) = @_;
243 return $self->search_related($rel)->new($values, $attrs);
246 =head2 create_related
248 my $new_obj = $obj->create_related('relname', \%col_data);
250 Creates a new item, similarly to new_related, and also inserts the item's data
251 into your storage medium. See the distinction between C<create> and C<new>
252 in L<DBIx::Class::ResultSet> for details.
259 my $obj = $self->search_related($rel)->create(@_);
260 delete $self->{related_resultsets}->{$rel};
266 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
268 Attempt to find a related object using its primary key or unique constraints.
269 See L<DBIx::Class::ResultSet/find> for details.
276 return $self->search_related($rel)->find(@_);
279 =head2 find_or_new_related
281 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
283 Find an item of a related class. If none exists, instantiate a new item of the
284 related class. The object will not be saved into your storage until you call
285 L<DBIx::Class::Row/insert> on it.
289 sub find_or_new_related {
291 my $obj = $self->find_related(@_);
292 return defined $obj ? $obj : $self->new_related(@_);
295 =head2 find_or_create_related
297 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
299 Find or create an item of a related class. See
300 L<DBIx::Class::ResultSet/find_or_create> for details.
304 sub find_or_create_related {
306 my $obj = $self->find_related(@_);
307 return (defined($obj) ? $obj : $self->create_related(@_));
310 =head2 update_or_create_related
312 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
314 Update or create an item of a related class. See
315 L<DBIx::Class::ResultSet/update_or_create> for details.
319 sub update_or_create_related {
322 return $self->related_resultset($rel)->update_or_create(@_);
325 =head2 set_from_related
327 $book->set_from_related('author', $author_obj);
328 $book->author($author_obj); ## same thing
330 Set column values on the current object, using related values from the given
331 related object. This is used to associate previously separate objects, for
332 example, to set the correct author for a book, find the Author object, then
333 call set_from_related on the book.
335 This is called internally when you pass existing objects as values to
336 L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to acessor.
338 The columns are only set in the local copy of the object, call L</update> to
339 set them in the storage.
343 sub set_from_related {
344 my ($self, $rel, $f_obj) = @_;
345 my $rel_obj = $self->relationship_info($rel);
346 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
347 my $cond = $rel_obj->{cond};
348 $self->throw_exception(
349 "set_from_related can only handle a hash condition; the ".
350 "condition for $rel is of type ".
351 (ref $cond ? ref $cond : 'plain scalar')
352 ) unless ref $cond eq 'HASH';
353 if (defined $f_obj) {
354 my $f_class = $self->result_source->schema->class($rel_obj->{class});
355 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
356 unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
359 $self->result_source->resolve_condition(
360 $rel_obj->{cond}, $f_obj, $rel));
364 =head2 update_from_related
366 $book->update_from_related('author', $author_obj);
368 The same as L</"set_from_related">, but the changes are immediately updated
373 sub update_from_related {
375 $self->set_from_related(@_);
379 =head2 delete_related
381 $obj->delete_related('relname', $cond, $attrs);
383 Delete any related item subject to the given conditions.
389 my $obj = $self->search_related(@_)->delete;
390 delete $self->{related_resultsets}->{$_[0]};
396 B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
401 =item Arguments: ($foreign_vals | $obj), $link_vals?
405 my $role = $schema->resultset('Role')->find(1);
406 $actor->add_to_roles($role);
407 # creates a My::DBIC::Schema::ActorRoles linking table row object
409 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
410 # creates a new My::DBIC::Schema::Role row object and the linking table
411 # object with an extra column in the link
413 Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
414 argument is a hash reference, the related object is created first with the
415 column values in the hash. If an object reference is given, just the linking
416 table object is created. In either case, any additional column values for the
417 linking table object can be specified in C<$link_vals>.
421 B<Currently only available for C<many-to-many> relationships.>
425 =item Arguments: (\@hashrefs | \@objs)
429 my $actor = $schema->resultset('Actor')->find(1);
430 my @roles = $schema->resultset('Role')->search({ role =>
431 { '-in' -> ['Fred', 'Barney'] } } );
433 $actor->set_roles(\@roles);
434 # Replaces all of $actor's previous roles with the two named
436 Replace all the related objects with the given reference to a list of
437 objects. This does a C<delete> B<on the link table resultset> to remove the
438 association between the current object and all related objects, then calls
439 C<add_to_$rel> repeatedly to link all the new objects.
441 Note that this means that this method will B<not> delete any objects in the
442 table on the right side of the relation, merely that it will delete the link
445 Due to a mistake in the original implementation of this method, it will also
446 accept a list of objects or hash references. This is B<deprecated> and will be
447 removed in a future version.
449 =head2 remove_from_$rel
451 B<Currently only available for C<many-to-many> relationships.>
455 =item Arguments: $obj
459 my $role = $schema->resultset('Role')->find(1);
460 $actor->remove_from_roles($role);
461 # removes $role's My::DBIC::Schema::ActorRoles linking table row object
463 Removes the link between the current object and the related object. Note that
464 the related object itself won't be deleted unless you call ->delete() on
465 it. This method just removes the link between the two objects.
469 Matt S. Trout <mst@shadowcatsystems.co.uk>
473 You may distribute this code under the same terms as Perl itself.