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