Fix a typo.
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / Joining.pod
1 =head1 NAME 
2
3 DBIx::Class::Manual::Joining - Manual on joining tables with DBIx::Class
4
5 =head1 DESCRIPTION
6
7 This document should help you to use L<DBIx::Class> if you are trying
8 to convert your normal SQL queries into DBIx::Class based queries, if
9 you use joins extensively (and also probably if you don't).
10
11 =head1 WHAT ARE JOINS
12
13 If you ended up here and you don't actually know what joins are yet,
14 then you should likely try the L<DBIx::Class::Manual::Intro>
15 instead. Skip this part if you know what joins are..
16
17 But I'll explain anyway. Assuming you have created your database in a
18 more or less sensible way, you will end up with several tables that
19 contain C<related> information. For example, you may have a table
20 containing information about C<CDs>, containing the CD title and it's
21 year of publication, and another table containing all the C<Track>s
22 for the CDs, one track per row.
23
24 When you wish to extract information about a particular CD and all
25 it's tracks, You can either fetch the CD row, then make another query
26 to fetch the tracks, or you can use a join. Compare:
27
28   SELECT ID, Title, Year FROM CD WHERE Title = 'Funky CD';
29   # .. Extract the ID, which is 10
30   SELECT Name, Artist FROM Tracks WHERE CDID = 10;
31
32   SELECT cd.ID, cd.Title, cd.Year, tracks.Name, tracks.Artist FROM CD JOIN Tracks ON CD.ID = tracks.CDID WHERE cd.Title = 'Funky CD';
33
34 So, joins are a way of extending simple select statements to include
35 fields from other, related, tables. There are various types of joins,
36 depending on which combination of the data you wish to retrieve, see
37 L<MySQL's doc on JOINs|http://dev.mysql.com/doc/refman/5.0/en/join.html>.
38
39 =head1 DEFINING JOINS AND RELATIONSHIPS
40
41 In L<DBIx::Class> each relationship between two tables needs to first
42 be defined in the L<ResultSource|DBIx::Class::Manual::Glossary/ResultSource> for the
43 table. If the relationship needs to be accessed in both directions
44 (i.e. Fetch all tracks of a CD, and fetch the CD data for a Track),
45 then it needs to be defined in both tables.
46
47 For the CDs/Tracks example, that means writing, in C<MySchema::CD>:
48
49   MySchema::CD->has_many('tracks', 'MySchema::Tracks');
50
51 And in C<MySchema::Tracks>:
52
53   MySchema::Tracks->belongs_to('cd', 'MySchema::CD', 'CDID');
54
55 There are several other types of relationships, they are more
56 comprehensively described in L<DBIx::Class::Relationship>.
57
58 =head1 USING JOINS
59
60 Once you have defined all your relationships, using them in actual
61 joins is fairly simple. The type of relationship that you chose
62 e.g. C<has_many>, already indicates what sort of join will be
63 performed. C<has_many> produces a C<LEFT JOIN> for example, which will
64 fetch all the rows on the left side, whether there are matching rows
65 on the right (table being joined to), or not. You can force other
66 types of joins in your relationship, see the
67 L<DBIx::Class::Relationship> docs.
68
69 When performing either a L<search|DBIx::Class::ResultSet/search> or a
70 L<find|DBIx::Class::ResultSet/find> operation, you can specify which
71 C<relations> to also fetch data from (or sort by), using the
72 L<join|DBIx::Class::ResultSet/join> attribute, like this:
73
74   $schema->resultset('CD')->search(
75     { 'Title' => 'Funky CD' },
76     { join      => 'tracks',
77       '+select' => [ 'tracks.Name', 'tracks.Artist' ],
78       '+as'     => [ 'TrackName', 'ArtistName' ]
79     }
80   );
81
82 If you don't recognise most of this syntax, you should probably go
83 read L<DBIx::Class::ResultSet/search> and
84 L<DBIx::Class::ResultSet/ATTRIBUTES>, but here's a quick break down:
85
86 The first argument to search is a hashref of the WHERE attributes, in
87 this case a simple restriction on the Title column. The second
88 argument is a hashref of attributes to the search, '+select' adds
89 extra columns to the select (from the joined table(s) or from
90 calculations), and '+as' gives aliases to those fields.
91
92 'join' specifies which C<relationships> to include in the query. The
93 distinction between C<relationships> and C<tables> is important here,
94 only the C<relationship> names are valid.
95
96 This example should magically produce SQL like the second select in
97 L</WHAT ARE JOINS> above.
98
99 =head1 COMPLEX JOINS AND STUFF
100
101 =head2 Across multiple relations
102
103 For simplicity in the example above, the C<Artist> was shown as a
104 simple text field in the C<Tracks> table, in reality, you'll want to
105 have the artists in their own table as well, thus to fetch the
106 complete set of data we'll need to join to the Artist table too.
107
108 In C<MySchema::Tracks>:
109
110   MySchema::Tracks->belongs_to('artist', 'MySchema::Artist', 'ArtistID');
111
112 The search:
113
114   $schema->resultset('CD')->search(
115     { 'Title' => 'Funky CD' },
116     { join      => { 'tracks' => 'artist' },
117       '+select' => [ 'tracks.Name', 'artist.Artist' ],
118       '+as'     => [ 'TrackName', 'ArtistName' ]
119     }
120   );
121
122 Which is:
123
124   SELECT me.ID, me.Title, me.Year, tracks.Name, artist.Artist FROM CD me JOIN Tracks tracks ON CD.ID = tracks.CDID JOIN Artists artist ON tracks.ArtistID = artist.ID WHERE me.Title = 'Funky CD';
125
126 To perform joins using relations of the tables you are joining to, use
127 a hashref to indicate the join depth. This can theoretically go as
128 deep as you like (warning, contrived examples!): 
129
130   join => { room => { table => 'leg' } }
131
132 To join two relations at the same level, use an arrayref instead:
133
134   join => { room => [ 'chair', 'table' ] } 
135
136 Or combine the two:
137
138   join => { room => [ 'chair', { table => 'leg' } ]
139
140 =head2 Table aliases
141
142 As an aside to all the discussion on joins, note that L<DBIx::Class>
143 uses the C<relation names> as table aliases. This is important when
144 you need to add grouping or ordering to your queries:
145
146   $schema->resultset('CD')->search(
147     { 'Title' => 'Funky CD' },
148     { join      => { 'tracks' => 'artist' },
149       order_by  => [ 'tracks.Name', 'artist.Artist' ],
150       '+select' => [ 'tracks.Name', 'artist.Artist' ],
151       '+as'     => [ 'TrackName', 'ArtistName' ]
152     }
153   );
154
155   SELECT me.ID, me.Title, me.Year, tracks.Name, artist.Artist FROM CD me JOIN Tracks tracks ON CD.ID = tracks.CDID JOIN Artists artist ON tracks.ArtistID = artist.ID WHERE me.Title = 'Funky CD' ORDER BY tracks.Name, artist.Artist;
156
157 This is essential if any of your tables have columns with the same names.
158
159 Note that the table of the resultsource the search was performed on, is always aliased to C<me>.
160
161 =head2 Joining to the same table twice
162
163 There is no magic to this, just do it. The table aliases will
164 automatically be numbered:
165
166   join => [ 'room', 'room' ]
167
168 The aliases are: C<room> and C<room_2>.
169
170 =cut
171