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 Valid attributes are as follows:
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.
107 =head2 register_relationship
111 =item Arguments: $relname, $rel_info
115 Registers a relationship on the class. This is called internally by
116 DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
120 sub register_relationship { }
122 =head2 related_resultset
126 =item Arguments: $relationship_name
128 =item Return Value: $related_resultset
132 $rs = $cd->related_resultset('artist');
134 Returns a L<DBIx::Class::ResultSet> for the relationship named
139 sub related_resultset {
141 $self->throw_exception("Can't call *_related as class methods")
144 my $rel_obj = $self->relationship_info($rel);
145 $self->throw_exception( "No such relationship ${rel}" )
148 return $self->{related_resultsets}{$rel} ||= do {
149 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
150 $attrs = { %{$rel_obj->{attrs} || {}}, %$attrs };
152 $self->throw_exception( "Invalid query: @_" )
153 if (@_ > 1 && (@_ % 2 == 1));
154 my $query = ((@_ > 1) ? {@_} : shift);
156 my $cond = $self->result_source->resolve_condition(
157 $rel_obj->{cond}, $rel, $self
159 if (ref $cond eq 'ARRAY') {
160 $cond = [ map { my $hash;
161 foreach my $key (keys %$_) {
162 my $newkey = $key =~ /\./ ? "me.$key" : $key;
163 $hash->{$newkey} = $_->{$key};
166 foreach my $key (grep { ! /\./ } keys %$cond) {
167 $cond->{"me.$key"} = delete $cond->{$key};
170 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
171 $self->result_source->related_source($rel)->resultset->search(
177 =head2 search_related
179 @objects = $rs->search_related('relname', $cond, $attrs);
180 $objects_rs = $rs->search_related('relname', $cond, $attrs);
182 Run a search on a related resultset. The search will be restricted to the
183 item or items represented by the L<DBIx::Class::ResultSet> it was called
184 upon. This method can be called on a ResultSet, a Row or a ResultSource class.
189 return shift->related_resultset(shift)->search(@_);
192 =head2 search_related_rs
194 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
196 This method works exactly the same as search_related, except that
197 it garauntees a restultset, even in list context.
201 sub search_related_rs {
202 return shift->related_resultset(shift)->search_rs(@_);
207 $obj->count_related('relname', $cond, $attrs);
209 Returns the count of all the items in the related resultset, restricted by the
210 current item or where conditions. Can be called on a
211 L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
212 L<DBIx::Class::Manual::Glossary/"Row"> object.
218 return $self->search_related(@_)->count;
223 my $new_obj = $obj->new_related('relname', \%col_data);
225 Create a new item of the related foreign class. If called on a
226 L<DBIx::Class::Manual::Glossary/"Row"> object, it will magically set any
227 primary key values into foreign key columns for you. The newly created item
228 will not be saved into your storage until you call L<DBIx::Class::Row/insert>
234 my ($self, $rel, $values, $attrs) = @_;
235 return $self->search_related($rel)->new($values, $attrs);
238 =head2 create_related
240 my $new_obj = $obj->create_related('relname', \%col_data);
242 Creates a new item, similarly to new_related, and also inserts the item's data
243 into your storage medium. See the distinction between C<create> and C<new>
244 in L<DBIx::Class::ResultSet> for details.
251 my $obj = $self->search_related($rel)->create(@_);
252 delete $self->{related_resultsets}->{$rel};
258 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
260 Attempt to find a related object using its primary key or unique constraints.
261 See L<DBIx::Class::ResultSet/find> for details.
268 return $self->search_related($rel)->find(@_);
271 =head2 find_or_new_related
273 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
275 Find an item of a related class. If none exists, instantiate a new item of the
276 related class. The object will not be saved into your storage until you call
277 L<DBIx::Class::Row/insert> on it.
281 sub find_or_new_related {
283 return $self->find_related(@_) || $self->new_related(@_);
286 =head2 find_or_create_related
288 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
290 Find or create an item of a related class. See
291 L<DBIx::Class::ResultSet/find_or_create> for details.
295 sub find_or_create_related {
297 my $obj = $self->find_related(@_);
298 return (defined($obj) ? $obj : $self->create_related(@_));
301 =head2 update_or_create_related
303 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
305 Update or create an item of a related class. See
306 L<DBIx::Class::ResultSet/update_or_create> for details.
310 sub update_or_create_related {
313 return $self->related_resultset($rel)->update_or_create(@_);
316 =head2 set_from_related
318 $book->set_from_related('author', $author_obj);
320 Set column values on the current object, using related values from the given
321 related object. This is used to associate previously separate objects, for
322 example, to set the correct author for a book, find the Author object, then
323 call set_from_related on the book.
325 The columns are only set in the local copy of the object, call L</update> to
326 set them in the storage.
330 sub set_from_related {
331 my ($self, $rel, $f_obj) = @_;
332 my $rel_obj = $self->relationship_info($rel);
333 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
334 my $cond = $rel_obj->{cond};
335 $self->throw_exception(
336 "set_from_related can only handle a hash condition; the ".
337 "condition for $rel is of type ".
338 (ref $cond ? ref $cond : 'plain scalar')
339 ) unless ref $cond eq 'HASH';
340 if (defined $f_obj) {
341 my $f_class = $self->result_source->schema->class($rel_obj->{class});
342 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
343 unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
346 $self->result_source->resolve_condition(
347 $rel_obj->{cond}, $f_obj, $rel));
351 =head2 update_from_related
353 $book->update_from_related('author', $author_obj);
355 The same as L</"set_from_related">, but the changes are immediately updated
360 sub update_from_related {
362 $self->set_from_related(@_);
366 =head2 delete_related
368 $obj->delete_related('relname', $cond, $attrs);
370 Delete any related item subject to the given conditions.
376 my $obj = $self->search_related(@_)->delete;
377 delete $self->{related_resultsets}->{$_[0]};
385 Matt S. Trout <mst@shadowcatsystems.co.uk>
389 You may distribute this code under the same terms as Perl itself.