documenting!
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Relationship / Base.pm
CommitLineData
55e2d745 1package DBIx::Class::Relationship::Base;
2
3use strict;
4use warnings;
5
1edd1722 6use base qw/DBIx::Class/;
55e2d745 7
8__PACKAGE__->mk_classdata('_relationships', { } );
9
10=head1 NAME
11
8918977e 12DBIx::Class::Relationship::Base - Inter-table relationships
55e2d745 13
14=head1 SYNOPSIS
15
16=head1 DESCRIPTION
17
30236e47 18This class provides methods to describe the relationships between the
19tables in your database model. These are the "bare bones" relationships
20methods, for predefined ones, look in L<DBIx::Class::Relationship>.
55e2d745 21
22=head1 METHODS
23
8091aa91 24=head2 add_relationship
503536d5 25
30236e47 26=head3 Arguments: ('relname', 'Foreign::Class', $cond, $attrs)
27
503536d5 28 __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs);
29
30The condition needs to be an SQL::Abstract-style representation of the
30236e47 31join between the tables. When resolving the condition for use in a JOIN,
32keys using the psuedo-table I<foreign> are resolved to mean "the Table on the
33other side of the relationship", and values using the psuedo-table I<self>
34are resolved to mean "the Table this class is representing". Other
35restrictions, such as by value, sub-select and other tables, may also be
36used. Please check your database for JOIN parameter support.
37
38For example, if you're creating a rel from Author to Book, where the Book
39table has a column author_id containing the ID of the Author row:
503536d5 40
30236e47 41 { 'foreign.author_id' => 'self.id' }
503536d5 42
8091aa91 43will result in the JOIN clause
503536d5 44
30236e47 45 author me JOIN book book ON bar.author_id = me.id
503536d5 46
30236e47 47You can specify as many foreign => self mappings as necessary. Each key/value
48pair provided in a hashref will be used as ANDed conditions, to add an ORed
49condition, use an arrayref of hashrefs. See the L<SQL::Abstract> documentation
50for more details.
8091aa91 51
52Valid attributes are as follows:
53
54=over 4
55
56=item join_type
57
58Explicitly specifies the type of join to use in the relationship. Any SQL
59join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
60command immediately before C<JOIN>.
61
62=item proxy
63
30236e47 64An arrayref containing a list of accessors in the foreign class to create in
8091aa91 65the main class. If, for example, you do the following:
66
30236e47 67 MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes', undef, {
68 proxy => [ qw/notes/ ],
69 });
8091aa91 70
30236e47 71Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do:
8091aa91 72
30236e47 73 my $cd = MyDB::Schema::CD->find(1);
74 $cd->notes('Notes go here'); # set notes -- LinerNotes object is
75 # created if it doesn't exist
8091aa91 76
77=item accessor
78
79Specifies the type of accessor that should be created for the relationship.
80Valid values are C<single> (for when there is only a single related object),
81C<multi> (when there can be many), and C<filter> (for when there is a single
82related object, but you also want the relationship accessor to double as
83a column accessor). For C<multi> accessors, an add_to_* method is also
84created, which calls C<create_related> for the relationship.
85
86=back
87
87c4e602 88=head2 register_relationship
89
90=head3 Arguments: ($relname, $rel_info)
71e65b39 91
30236e47 92Registers a relationship on the class. This is called internally by
93L<DBIx::Class::ResultSourceProxy> to set up Accessors and Proxies.
71e65b39 94
55e2d745 95=cut
96
71e65b39 97sub register_relationship { }
98
30236e47 99=head2 related_resultset($name)
100
101 $rs = $obj->related_resultset('related_table');
102
103Returns a L<DBIx::Class::ResultSet> for the relationship named $name.
104
105=cut
106
107sub related_resultset {
108 my $self = shift;
109 $self->throw_exception("Can't call *_related as class methods") unless ref $self;
110 my $rel = shift;
111 my $rel_obj = $self->relationship_info($rel);
112 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
113
114 return $self->{related_resultsets}{$rel} ||= do {
115 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
116 $attrs = { %{$rel_obj->{attrs} || {}}, %$attrs };
117
118 $self->throw_exception( "Invalid query: @_" ) if (@_ > 1 && (@_ % 2 == 1));
119 my $query = ((@_ > 1) ? {@_} : shift);
120
121 my $cond = $self->result_source->resolve_condition($rel_obj->{cond}, $rel, $self);
122 if (ref $cond eq 'ARRAY') {
123 $cond = [ map { my $hash;
124 foreach my $key (keys %$_) {
125 my $newkey = $key =~ /\./ ? "me.$key" : $key;
126 $hash->{$newkey} = $_->{$key};
127 }; $hash } @$cond ];
128 } else {
129 foreach my $key (grep { ! /\./ } keys %$cond) {
130 $cond->{"me.$key"} = delete $cond->{$key};
131 }
132 }
133 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
134 $self->result_source->related_source($rel)->resultset->search($query, $attrs);
135 };
136}
137
8091aa91 138=head2 search_related
503536d5 139
30236e47 140 $rs->search_related('relname', $cond, $attrs);
141
142Run a search on a related resultset. The search will be restricted to the
143item or items represented by the L<DBIx::Class::ResultSet> it was called
144upon. This method can be called on a ResultSet, a Row or a ResultSource class.
503536d5 145
146=cut
147
55e2d745 148sub search_related {
ff7bb7a1 149 return shift->related_resultset(shift)->search(@_);
b52e9bf8 150}
151
152=head2 count_related
153
7be93b07 154 $obj->count_related('relname', $cond, $attrs);
b52e9bf8 155
30236e47 156Returns the count of all the items in the related resultset, restricted by
157the current item or where conditions. Can be called on a L<DBIx::Classl::Manual::Glossary/"ResultSet"> or a L<DBIx::Class::Manual::Glossary/"Row"> object.
158
b52e9bf8 159=cut
160
161sub count_related {
162 my $self = shift;
163 return $self->search_related(@_)->count;
55e2d745 164}
165
30236e47 166=head2 new_related
167
168 my $new_obj = $obj->new_related('relname', \%col_data);
169
170Create a new item of the related foreign class. If called on a
171L<DBIx::Class::Manual::Glossary/"Row"> object, it will magically
172set any primary key values into foreign key columns for you. The newly
173created item will not be saved into your storage until you call C<insert>
174on it.
175
176=cut
177
178sub new_related {
179 my ($self, $rel, $values, $attrs) = @_;
180 return $self->search_related($rel)->new($values, $attrs);
181}
182
8091aa91 183=head2 create_related
503536d5 184
30236e47 185 my $new_obj = $obj->create_related('relname', \%col_data);
186
187Creates a new item, similarly to new_related, and also inserts the item's data
188into your storage medium. See the distinction between C<create> and C<new>
189in L<DBIx::Class::ResultSet> for details.
503536d5 190
191=cut
192
55e2d745 193sub create_related {
3842b955 194 my $self = shift;
fea3d045 195 my $rel = shift;
64acc2bc 196 my $obj = $self->search_related($rel)->create(@_);
197 delete $self->{related_resultsets}->{$rel};
198 return $obj;
55e2d745 199}
200
8091aa91 201=head2 find_related
503536d5 202
30236e47 203 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
204
205Attempt to find a related object using its primary key or unique constraints.
206See C<find> in L<DBIx::Class::ResultSet> for details.
503536d5 207
208=cut
209
1a14aa3f 210sub find_related {
211 my $self = shift;
212 my $rel = shift;
716b3d29 213 return $self->search_related($rel)->find(@_);
1a14aa3f 214}
215
8091aa91 216=head2 find_or_create_related
503536d5 217
30236e47 218 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
219
220Find or create an item of a related class. See C<find_or_create> in
221L<DBIx::Class::ResultSet> for details.
503536d5 222
223=cut
224
55e2d745 225sub find_or_create_related {
226 my $self = shift;
1a14aa3f 227 return $self->find_related(@_) || $self->create_related(@_);
55e2d745 228}
229
8091aa91 230=head2 set_from_related
503536d5 231
30236e47 232 $book->set_from_related('author', $author_obj);
233
234Set column values on the current object, using related values from the given
235related object. This is used to associate previously separate objects, for
236example, to set the correct author for a book, find the Author object, then
237call set_from_related on the book.
238
239The columns are only set in the local copy of the object, call C<update> to set
240them in the storage.
503536d5 241
242=cut
243
55e2d745 244sub set_from_related {
245 my ($self, $rel, $f_obj) = @_;
4685e006 246 my $rel_obj = $self->relationship_info($rel);
701da8c4 247 $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
55e2d745 248 my $cond = $rel_obj->{cond};
701da8c4 249 $self->throw_exception( "set_from_related can only handle a hash condition; the "
55e2d745 250 ."condition for $rel is of type ".(ref $cond ? ref $cond : 'plain scalar'))
251 unless ref $cond eq 'HASH';
7fb16f1a 252 my $f_class = $self->result_source->schema->class($rel_obj->{class});
701da8c4 253 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
55e2d745 254 unless $f_obj->isa($f_class);
fde6e28e 255 $self->set_columns(
256 $self->result_source->resolve_condition(
257 $rel_obj->{cond}, $f_obj, $rel));
55e2d745 258 return 1;
259}
260
8091aa91 261=head2 update_from_related
503536d5 262
30236e47 263 $book->update_from_related('author', $author_obj);
264
265As C<set_from_related>, but the changes are immediately updated onto your
266storage.
503536d5 267
268=cut
269
55e2d745 270sub update_from_related {
271 my $self = shift;
272 $self->set_from_related(@_);
273 $self->update;
274}
275
8091aa91 276=head2 delete_related
503536d5 277
30236e47 278 $obj->delete_related('relname', $cond, $attrs);
279
280Delete any related item subject to the given conditions.
503536d5 281
282=cut
283
55e2d745 284sub delete_related {
285 my $self = shift;
64acc2bc 286 my $obj = $self->search_related(@_)->delete;
287 delete $self->{related_resultsets}->{$_[0]};
288 return $obj;
55e2d745 289}
290
2911;
292
55e2d745 293=head1 AUTHORS
294
daec44b8 295Matt S. Trout <mst@shadowcatsystems.co.uk>
55e2d745 296
297=head1 LICENSE
298
299You may distribute this code under the same terms as Perl itself.
300
301=cut
302