reorg due to new purpose
[dbsrgits/dbix-class-introduction-presentation.git] / slideshow.html
CommitLineData
52d980cb 1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
4<html xmlns="http://www.w3.org/1999/xhtml">
5
6<head>
7<title>DBIx::Class (aka DBIC)</title>
8<!-- metadata -->
9<meta name="contributor" content="youcan[64]netzgesta[46]de" />
10<meta name="publisher" content="s5.netzgesta.de" />
11<meta name="description" content="S5 1.3 is a very flexible and lightweight slide show system available for anyone to use (including transitions and scalable fonts and images)" />
12<meta name="keywords" content="S5, version 1.3, slide show, presentation-mode, projection-mode, powerpoint-like, scala-like, keynote-like, incremental display, scalable fonts, scalable images, transitions, notes, osf, xoxo, css, javascript, xhtml, public domain" />
13
14<meta name="generator" content="S5" />
15<meta name="version" content="1" />
16<meta name="subject" content="DBIx::Class" />
17<meta name="author" content="See first slide" />
18<meta name="company" content="N/A" />
19<meta name="robots" content="index, follow" />
20<meta name="revisit-after" content="7 days" />
21<!-- meta additionally -->
22<meta http-equiv="content-type" content="text/html; charset=utf-8" />
23<meta http-equiv="Content-Script-Type" content="text/javascript" />
24<meta http-equiv="Content-Style-Type" content="text/css" /><!-- configuration parameters -->
25<meta name="defaultView" content="slideshow" />
26<meta name="controlVis" content="hidden" />
27<!-- configuration transition extension -->
28<meta name="tranSitions" content="true" />
29<meta name="fadeDuration" content="500" />
30<meta name="incrDuration" content="250" />
31<!-- configuration autoplay extension -->
32<meta name="autoMatic" content="false" />
33<meta name="playLoop" content="true" />
34<meta name="playDelay" content="10" />
35<!-- configuration audio extension -->
36<meta name="audioSupport" content="false" />
37<meta name="audioVolume" content="0" />
38<meta name="audioError" content="false" />
39<!-- configuration audio debug -->
40<meta name="audioDebug" content="false" />
41<!-- style sheet links -->
42<link rel="stylesheet" href="ui/scala_utf/slides.css" type="text/css" media="projection" id="slideProj" />
43<link rel="stylesheet" href="ui/scala_utf/outline.css" type="text/css" media="screen" id="outlineStyle" />
44<link rel="stylesheet" href="ui/scala_utf/print.css" type="text/css" media="print" id="slidePrint" />
45<link rel="stylesheet" href="ui/scala_utf/opera.css" type="text/css" media="projection" id="operaFix" />
46<!-- embedded styles -->
47<style type="text/css" media="all">
48.imgcon {width: 100%; margin: 0 auto; padding: 0; text-align: center;}
49#anim {width: 33%; height: 320px; position: relative;}
50#anim img {position: absolute; top: 0px; left: 0px;}
51.red {color: red;}
52.grey {color: gray;}
53</style>
54<!-- S5 JS -->
55<script src="ui/scala_utf/slides.js" type="text/javascript"></script>
56</head>
57<body>
58
59<div class="layout">
60 <div id="controls"><!-- DO NOT EDIT --></div>
61 <div id="currentSlide"><!-- DO NOT EDIT --></div>
62 <div id="header"></div>
63 <div id="footer">
64 <h1>DBIx::Class Introduction</h1>
65 <h2>YAPC::NA 2010</h2>
66 </div>
67</div>
68
69<div class="presentation">
70
71 <div class="slide">
72 <h1>DBIX::Class (aka DBIC)</h1>
73 <h3>for (advanced) beginners</h3>
0cffcad7 74 </div>
75
76 <div class="slide">
77 <h1>Authors</h1>
78 <h4>Originally Leo Lapworth @ LPW 2009</h4>
79 <h4>Matthew S. Trout</h4>
0cffcad7 80 <h4>Justin D. Hunter</h4>
5cac74c7 81 <h4>Arthur Axel "fREW" Schmidt</h4>
52d980cb 82 </div>
83
84 <div class="slide">
7365a110 85 <h1>What's up guys?</h1>
0cffcad7 86 <div class="notes">
87 <ul>
88 <li>How many people have designed a database with Foreign Keys?</li>
89 <li>How many people have used any ORM?<ul>
90 <li>In Perl?<ul>
91 <li>DBIC?</li>
92 <li> Class::DBI? </li>
93 <li> Rose::DB? </li>
94 <li> Fey? </li>
95 <li> Others? </li>
96 </ul></li>
97 <li>AR? </li>
98 <li> DataMapper? </li>
99 <li>(N)Hibernate?</li>
100 </ul></li>
101 </ul>
102 </div>
52d980cb 103 </div>
104
105 <div class="slide">
106 <h1>DBIx::Class?</h1>
107 <ul>
108 <li>ORM (object relational mapper)</li>
109 <li>SQL &lt;-&gt; OO (using objects instead of SQL)</li>
110 <li>Simple, powerful, complex, fab and confusing</li>
111 <li>There are many ORMs, DBIx::Class just happens to be the best in Perl (personal opinion)</li>
112 </ul>
113 </div>
114
115 <div class="slide">
7365a110 116 <h1>Purpose</h1>
117 <p>The purpose of this talk is to show you as many features of
118 DBIx::Class in 40 minutes
119 so that when you need to do something with it later you will
120 know what's possible</p>
52d980cb 121 </div>
122
123 <div class="slide">
7365a110 124 <h1>Basic CRUD</h1>
52d980cb 125 <ul>
126 <li><strong>C</strong> - Create</li>
127 <li><strong>R</strong> - Read</li>
128 <li><strong>U</strong> - Update</li>
129 <li><strong>D</strong> - Delete</li>
130 </ul>
131 </div>
132
133 <div class="slide">
5cac74c7 134 <h1>SQL: Create</h1>
52d980cb 135<pre>my $sth = $dbh-&gt;prepare('
136 INSERT INTO books
01b7b88c 137 (title, author_id)
52d980cb 138 values (?,?)
139');
140
141$sth-&gt;execute(
142 'A book title', $author_id
143);</pre>
144 </div>
145
146 <div class="slide">
5cac74c7 147 <h1>DBIC: Create</h1>
01b7b88c 148<pre>my $book = $book_rs-&gt;create({
149 title =&gt; 'A book title',
150 author_id =&gt; $author_id,
52d980cb 151});</pre>
7365a110 152 <p>Don't need to work to pair placeholders and values</p>
52d980cb 153 </div>
154
155 <div class="slide">
5cac74c7 156 <h1>DBIC: Create</h1>
01b7b88c 157<pre>my $pratchett = $author_rs-&gt;create({
52d980cb 158 name =&gt; 'Terry Pratchett',
159});</pre>
160 </div>
161
162 <div class="slide">
5cac74c7 163 <h1>DBIC: Create</h1>
52d980cb 164<pre>my $book = $pratchett-&gt;create_related(
165 <strong>books</strong> =&gt; {
166 title =&gt; 'Another Discworld book',
167});</pre>
168<strong>or</strong>
169<pre>my $book = $pratchett-&gt;add_to_<strong>books</strong>({
170 title =&gt; 'Another Discworld book',
171});</pre>
7365a110 172 <p>Automaticaly fills in foreign key for you</p>
52d980cb 173 </div>
174
175 <div class="slide">
7365a110 176 <h1>SQL: Read</h1>
177<pre>my $sth = $dbh-&gt;prepare('
178 SELECT title,
179 authors.name as author_name
180 FROM books, authors
181 WHERE books.author = authors.id
182');</pre>
183 </div>
184
185 <div class="slide">
186 <h1>SQL: Read</h1>
187<pre>while( my $book = $sth-&gt;fetchrow_hashref() ) {
188 print 'Author of '
189 . $book-&gt;{title}
190 . ' is '
191 . $book-&gt;{author_name}
192 . "\n";
193}</pre>
52d980cb 194 </div>
195
196 <div class="slide">
5cac74c7 197 <h1>DBIC: Read</h1>
01b7b88c 198<pre>my $book = $book_rs-&gt;find($book_id);
52d980cb 199
01b7b88c 200my $book = $book_rs-&gt;search({
52d980cb 201 title =&gt; 'A book title',
5cac74c7 202}, { rows =&gt; 1 })-&gt;single;
52d980cb 203
01b7b88c 204my @books = $book_rs-&gt;search({
52d980cb 205 author =&gt; $author_id,
206})-&gt;all;</pre>
7365a110 207 <p>TMTOWTDI</p>
52d980cb 208 </div>
209
210 <div class="slide">
5cac74c7 211 <h1>DBIC: Read</h1>
212<pre>while( my $book = $books_rs-&gt;next ) {
52d980cb 213 print 'Author of '
214 . $book-&gt;title
215 . ' is '
216 . $book-&gt;author-&gt;name
217 . "\n";
218}</pre>
219 </div>
220
221 <div class="slide">
5cac74c7 222 <h1>DBIC: Read</h1>
01b7b88c 223<pre>my $resultset = $book_rs-&gt;search({
52d980cb 224 author =&gt; $author_id,
225});</pre>
226 <p>Search takes SQL::Abstract formatted queries</p>
227 <pre>&gt; perldoc SQL::Abstract</p>
228 </div>
229
230 <div class="slide">
7365a110 231 <h1>SQL: Update</h1>
232<pre>my $update = $dbh-&gt;prepare('
233 UPDATE books
234 SET title = ?
235 WHERE id = ?
236');
237
238$update-&gt;execute(
239 'New title',<strong>$book_id</strong>
240);</pre>
241 </div>
242
243 <div class="slide">
5cac74c7 244 <h1>DBIC: Update</h1>
52d980cb 245<pre>$book-&gt;update({
246 title =&gt; 'New title',
247});</pre>
248 </div>
249
250 <div class="slide">
7365a110 251 <h1>SQL: Delete</h1>
252<pre>my $delete = $dbh-&gt;prepare('
253 DELETE FROM books
254 WHERE id = ?
255');
256
257$delete-&gt;execute(<strong>$book_id</strong>);</pre>
258 </div>
259
260 <div class="slide">
5cac74c7 261 <h1>DBIC: Delete</h1>
52d980cb 262<pre>$book-&gt;delete;</pre>
263 </div>
264
265 <div class="slide">
266 <h1>Creating models</h1>
267 </div>
268
269 <div class="slide">
451b57c2 270<pre>package Foo::Schema::Result::Author;
492be2ae 271__PACKAGE__-&gt;table('authors');
272__PACKAGE__-&gt;add_columns(
273 id =&gt; {
01b7b88c 274 data_type =&gt; 'int',
275 is_auto_increment =&gt; 1
492be2ae 276 },
277 title =&gt; {
278 data_type =&gt; 'varchar',
279 is_nullable =&gt; 1,
280 size =&gt; 255,
281 },
282);
283__PACKAGE__-&gt;set_primary_key('id');
284__PACKAGE__-&gt;has_many( books =&gt;
451b57c2 285 'Foo::Schema::Result::Book', 'author_id'
492be2ae 286);
2871;
288</pre>
289 </div>
290
291 <div class="slide">
01b7b88c 292<pre style="float: left; font-size: 80%;">package Foo::Schema::Result::Book;
492be2ae 293use strict; use warnings;
294__PACKAGE__-&gt;table('books');
295__PACKAGE__-&gt;add_columns(
296 id =&gt; {
01b7b88c 297 data_type =&gt; 'int',
298 is_auto_increment =&gt; 1
492be2ae 299 },
300 name =&gt; {
301 data_type =&gt; 'varchar',
302 is_nullable =&gt; 1,
303 size =&gt; 255,
304 },
01b7b88c 305</pre>
306<pre style="float: left; font-size: 80%;">
492be2ae 307 author_id =&gt; {
308 data_type =&gt; 'int',
309 size =&gt; 8,
492be2ae 310 },
311);
312__PACKAGE__-&gt;set_primary_key('id');
313__PACKAGE__-&gt;belongs_to( author =&gt;
451b57c2 314 'Foo::Schema::Result::Author', 'author_id'
492be2ae 315);
3161;
317</pre>
52d980cb 318 </div>
319
320 <div class="slide">
9158dee5 321 <h1>-&gt;deploy</h1>
322 <p>Perl -&gt; DB</p>
323<pre>my $schema = Foo::Schema-&gt;connect($dsn, $user, $pass);
324$schema-&gt;deploy
325</pre>
326<p>See also: <a href="http://search.cpan.org/perldoc?DBIx::Class::DeploymentHandler">DBIx::Class::DeploymentHandler</a></p>
327 </div>
328
329 <div class="slide">
52d980cb 330 <h1>Schema::Loader</h1>
9158dee5 331 <p>DB -&gt; Perl</p>
451b57c2 332<pre>package Foo::Schema;
c7321880 333use strict; use warnings;
334use base 'DBIx::Class::Schema::Loader';
335__PACKAGE__-&gt;loader_options({
336 naming =&gt; 'v7',
337 debug =&gt; $ENV{DBIC_TRACE},
338});
3391;
340
341# elsewhere...
342
451b57c2 343my $schema = Foo::Schema-&gt;connect($dsn, $user, $pass);
c7321880 344</pre>
52d980cb 345 </div>
346
347 <div class="slide">
6e5edefe 348 <h1>Splitting Logic Cleanly</h1>
451b57c2 349 <p>Foo::Schema::Result::Bar = individual row</p>
350 <p>Foo::Schema::ResultSet::Bar = searches / table </p>
52d980cb 351 </div>
352
353 <div class="slide">
6e5edefe 354 <h1>Using your Schema</h1>
355<pre>#!perl
356use strict; use warnings;
357use lib 'lib';
451b57c2 358use Foo::Schema;
359my $schema = Foo::Schema-&gt;connect($dns, $user, $pass);
6e5edefe 360my $author_rs = $schema-&gt;resultset('Author');
361my $author = $author_rs-&gt;create({
362 name =&gt; 'Douglas Adams',
363});
364my $book = $author-&gt;add_to_books({
365 title =&gt; '42',
366});
367</pre>
52d980cb 368 </div>
369
370 <div class="slide">
371 <h1>DEBUGGING</h1>
372 <pre>DBIC_TRACE=1 ./your_script.pl</pre>
373 </div>
374
375 <div class="slide">
52d980cb 376 <h1>SQL - debugging</h1>
377<pre>INSERT INTO authors (name)
378 VALUES (?): 'Douglas Adams'
379
380INSERT INTO books (author, title)
381 VALUES (?, ?): '5', '42'</pre>
382 </div>
383
384 <div class="slide">
385 <h1>overloading</h1>
451b57c2 386<pre>Foo::Schema::Result::Book
387Foo::Schema::ResultSet::Book
388Foo::Schema::Result::Author
389Foo::Schema::ResultSet::Book</pre>
52d980cb 390 </div>
391
392 <div class="slide">
393 <h1>Result::</h1>
2a65778d 394<pre>package Foo::Schema::Result::Book;
395use base 'DBIx::Class::Core';
52d980cb 396use strict;
397use warnings;
398
6e5edefe 399# Result code here
400
52d980cb 401sub isbn {
402 my $self = shift;
403
404 # search amazon or something
405 my $api = Amazon::API-&gt;book({
406 title =&gt; $self-&gt;title
407 });
408
409 return $api-&gt;isbn;
410}
411
4121;</pre>
413 </div>
414
415 <div class="slide">
416 <h1>Result::</h1>
417<pre>print $book-&gt;isbn;</pre>
418 </div>
419
420 <div class="slide">
421 <h1>Result:: (inflating)</h1>
2a65778d 422<pre>package Foo::Schema::Result::Book;
423use base 'DBIx::Class::Core';
52d980cb 424use strict;
425use warnings;
426
451b57c2 427# Result code here
428
429__PACKAGE__-&gt;load_components('InflateColumn');
52d980cb 430use DateTime::Format::MySQL;
431
432__PACKAGE__-&gt;<strong>inflate_column</strong>(
433 <strong>date_published</strong> =&gt; {
434 inflate =&gt; sub { DateTime::Format::MySQL-&gt;parse_date(shift) },
435 deflate =&gt; sub { shift-&gt;ymd},
451b57c2 436 },
52d980cb 437);
438# Automatic see: DBIx::Class::InflateColumn::DateTime</pre>
439 </div>
440
441 <div class="slide">
52d980cb 442 <h1>Result:: (deflating)</h1>
443<pre>$book-&gt;date_published(DateTime-&gt;now);
444$book-&gt;update;</pre>
445 </div>
446
447 <div class="slide">
448 <h1>Result:: (inflating)</h1>
449<pre>my $date_published = $book-&gt;date_published;
450print $date_published-&gt;month_abbr;</pre>
451
452<strong><em>Nov</em></strong>
453 </div>
454
455 <div class="slide">
456 <h1>ResultSets::</h1>
41a0eb8e 457<pre>package Foo::Schema::ResultSet::Books;
52d980cb 458use base 'DBIx::Class::ResultSet';
459sub the_ultimate_books {
460 my $self = shift;
461 return $self-&gt;search({ title =&gt; { -like =&gt; '%42%' } });
462}
463sub by_author {
464 my ( $self, $author ) = @_;
465 return $self-&gt;search({ author =&gt; $author-&gt;id })
466}
467
4681;</pre>
469 </div>
470
471 <div class="slide">
472 <h1>ResultSets::</h1>
41a0eb8e 473<pre>use Foo::Schema;
451b57c2 474my $schema = Foo::Schema-&gt;connect(...);
475my $book_rs = Foo::Schema-&gt;resultset('Book');
476my $book_search = $book_rs-&gt;the_ultimate_books;
477my @books = $book_search-&gt;all;</pre>
52d980cb 478 </div>
479
480 <div class="slide">
451b57c2 481 <h1>ResultSets: Chaining</h1>
482<pre>
01b7b88c 483my $book_rs = $schema-&gt;resultset('Book');
484my $author_rs = $schema-&gt;resultset('Author');
485my $author = $author_rs-&gt;search({ name =&gt; 'Douglas Adams' })-&gt;single;
486$book_rs = $book_rs-&gt;the_ultimate_books-&gt;by_author($author);
487my @books = $book_rs-&gt;all;</pre>
52d980cb 488 </div>
489
490 <div class="slide">
451b57c2 491 <h1>ResultSets: Chaining</h1>
492<pre>$book_rs = $schema-&gt;resultset('Book')
52d980cb 493 -&gt;the_ultimate_books
494 -&gt;by_author($author);</pre>
495or
496
451b57c2 497<pre>my $book_rs = $schema-&gt;resultset('Book')
2a65778d 498 -&gt;the_ultimate_books;
52d980cb 499$book_rs = $book_rs-&gt;by_author($author);</pre>
500<pre># Debug (SQL):
501
502# SELECT me.id, me.title, me.date_published, me.author
503# FROM books me
504# WHERE ( ( ( author = ? ) AND ( title LIKE ? ) ) ): '5', '%42%'
505# WHERE ( ( ( author = ? ) AND ( title LIKE ? ) ) ): '5', '%42%'</pre>
506 </div>
507
508 <div class="slide">
01b7b88c 509 <h1>ResultSets: Chaining</h1>
510<pre>my $rs = $book_rs
52d980cb 511 -&gt;category('childrens')
512 -&gt;by_author($author)
513 -&gt;published_after('1812')
514 -&gt;first_page_contains('once upon')
515 -&gt;rating_greater_than(4);
516
517my @books = $rs-&gt;all;</pre>
518 </div>
519
520 <div class="slide">
521 <h1>overloading before new record</h1>
2a65778d 522 <pre>package Foo::Schema::Result::Author;
523use base 'DBIx::Class::Core';
52d980cb 524
525sub new {
526 my ( $class, $attrs ) = @_;
527 # Mess with $attrs
528 my $new = $class-&gt;next::method($attrs);
529 return $new
530}
531
5321;</pre>
533
534 <div class="slide">
6548782a 535 <h1>Relationships</h1>
52d980cb 536 </div>
537
538 <div class="slide">
6548782a 539 <h1>Multiple Authors</h1>
01b7b88c 540 <p>We want to allow a book to be by more than one author</p>
52d980cb 541 </div>
542
543 <div class="slide">
544 <h1>a few relationships</h1>
9158dee5 545 <img src="img/afewrels.png" />
52d980cb 546 </div>
547
548 <div class="slide">
6548782a 549 <h1>Join Table</h1>
52d980cb 550<pre>CREATE TABLE author_and_books(
6548782a 551 book_id int(8),
552 author_id int(8),
553 foreign key (book_id) references books(id),
554 foreign key (author_id) references authors(id)
52d980cb 555) engine = InnoDB DEFAULT CHARSET=utf8;
556
01b7b88c 557ALTER TABLE `books` DROP `author_id`;</pre>
52d980cb 558 </div>
559
560 <div class="slide">
561 <h1>has_many</h1>
9158dee5 562 <img src="img/hasmany1.png" />
52d980cb 563 </div>
564
565 <div class="slide">
566 <h1>has_many</h1>
6548782a 567<pre>package Foo::Schema::<strong>Result::Book</strong>;
52d980cb 568
6548782a 569__PACKAGE__-&gt;has_many( author_and_books =&gt;
570 'Foo::Schema::Result::Author_Book', 'book_id'
52d980cb 571);
52d980cb 572 </div>
573
574 <div class="slide">
575 <h1>belongs_to</h1>
9158dee5 576 <img src="img/belongsto1.png" />
52d980cb 577 </div>
578
579 <div class="slide">
580 <h1>belongs_to</h1>
6548782a 581<pre>package Foo::Schema::<strong>Result::Author_Book</strong>;
52d980cb 582
583__PACKAGE__-&gt;belongs_to(
6548782a 584 book =&gt;
585 'Foo::Schema::Result::Book', 'book_id'
52d980cb 586);
587</pre>
588 </div>
589
590 <div class="slide">
591 <h1>same for Authors</h1>
9158dee5 592 <img src="img/authors.png" />
52d980cb 593 </div>
594
595 <div class="slide">
52d980cb 596 <h1>many_to_many</h1>
9158dee5 597 <img src="img/m2m.png" />
52d980cb 598 </div>
599
600 <div class="slide">
601 <h1>many_to_many</h1>
2a65778d 602 <pre>package Foo::Schema::<strong>Result::Book</strong>;
603use base 'DBIx::Class::Core';
52d980cb 604
605__PACKAGE__-&gt;many_to_many(
6548782a 606 authors =&gt; 'author_and_books', 'author'
52d980cb 607);
608
6091;
6548782a 610</pre>
52d980cb 611 </div>
612
613 <div class="slide">
614 <h1>many_to_many</h1>
2a65778d 615 <pre>package Foo::Schema::<strong>Result::Book</strong>;
616use base 'DBIx::Class::Core';
52d980cb 617
618__PACKAGE__-&gt;many_to_many(
619 authors <strong># Accessor name</strong>
620 =&gt; "author_and_books", <strong># has_many</strong>
621 'author' <strong># foreign relationship name</strong>
622);
623
6241;</pre>
625 </div>
626
627 <div class="slide">
628 <h1>many_to_many</h1>
2a65778d 629 <pre>package Foo::Schema::Result::Author;
630use base 'DBIx::Class::Core';
52d980cb 631
632__PACKAGE__-&gt;many_to_many(
633 "books" <strong># Accessor Name</strong>
634 =&gt; "author_and_books", <strong># has_many accessor_name</strong>
635 'book' <strong># foreign relationship name</strong>
636);
637
6381;
6548782a 639</pre>
52d980cb 640 </div>
641
642 <div class="slide">
6c562ff1 643 <h1>Using many_to_many</h1>
644 <pre>#!perl
41a0eb8e 645use Foo::Schema;
6c562ff1 646my $schema = Foo::Schema-&gt;connect(...);
647my $author_rs = $schema-&gt;resultset('Authors');
01b7b88c 648my $author = $author_rs-&gt;search({
52d980cb 649 name =&gt; 'Douglas Adams',
650})-&gt;single;
651$author-&gt;add_to_books({
652 title =&gt; 'A new book',
653});</pre>
654 </div>
655
656 <div class="slide">
657 <h1>using many_to_many</h1>
01b7b88c 658 <pre>my $author = $author_rs-&gt;search({
52d980cb 659 name =&gt; 'Douglas Adams',
660})-&gt;single;
661<strong>$author-&gt;add_to_books({
662 title =&gt; 'A new book',
663});</strong>
664
665# SELECT me.id, me.name FROM authors me
666# WHERE ( name = ? ): 'Douglas Adams';
667# INSERT INTO books (title) VALUES (?): 'A new book';
668# INSERT INTO author_and_books (author, book)
669# VALUES (?, ?): '5', '2';</pre>
670 </div>
671
672 <div class="slide">
673 <h1>using many_to_many</h1>
674 <pre>$author-&gt;add_to_books($book);
675
676$book-&gt;add_to_authors($author_1);
677$book-&gt;add_to_authors($author_2);</pre>
678 </div>
679
680 <div class="slide">
52d980cb 681 <h1>errors</h1>
682 <p>Read them closely!</p>
683 </div>
684
685 <div class="slide">
686 <h1>error messages</h1>
01b7b88c 687<pre>DBIx::Class::Schema::Loader::connection(): Failed to load external
688class definition for 'Foo::Schema::Result::Authors': Can't locate object
689method "many_to_many" via package "Foo::Schema::Result::Author" at
690lib/Foo/Schema/Result/Authors.pm line 9.Compilation failed in require at
691/Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.</pre>
52d980cb 692 </div>
693
694 <div class="slide">
695 <h1>error messages</h1>
01b7b88c 696<pre>DBIx::Class::Schema::Loader::connection(): Failed to load external
697class definition for 'Foo::Schema::Result::Authors': Can't locate object
698method "many_to_many" via package "Foo::Schema::<strong>Result::Author</strong>" at
699lib/Foo/Schema/<strong>Result/Authors.pm</strong> line 9.Compilation failed in require at
700/Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.</pre>
52d980cb 701 </div>
702
703 <div class="slide">
704 <h1>errors</h1>
705 <ul>
706 <li>Turn on debugging</li>
707 <li>Read error messages (sometimes useful!)</li>
708 <li>Check field names</li>
709 <li>Check package names</li>
710 <li>Check which database you are connected to (dev/test/live?) - repeat above</li>
711 </ul>
712 </div>
713
714 <div class="slide">
9158dee5 715 <h1>LOTS more Features</h1>
716 <ul>
717 <li>FilterColumn</li>
718 <li>Transactions</li>
719 <li>HashRefInflator</li>
720 <li>Subqueries</li>
721 <li>ResultSetColumn</li>
01b7b88c 722 <li>Aggregate Queries</li>
9158dee5 723 </ul>
724 </div>
725
726 <div class="slide">
52d980cb 727 <h1>bonus slides!</h1>
728 </div>
729
730 <div class="slide">
731 <h1>Template Toolkit</h1>
732 <ul>
733 <li><pre>[% author.books.count %]</pre> not working?</li>
734 <li>TT all methods are called in list context</li>
735 <li><pre>[% author.books<strong>_rs</strong>.count %]</pre> scalar context</li>
736 <li><em>Available for all relationships</em></li>
737 </ul>
738 </div>
739
740 <div class="slide">
741 <h1>Catalyst</h1>
0cffcad7 742 <pre>package Your::App::Model::<strong>Foo</strong>;
41a0eb8e 743use base qw(<strong>Catalyst::Model::Schema::Schema</strong>);
52d980cb 744
745use strict;
746use warnings;
747
748__PACKAGE__-&gt;config(
41a0eb8e 749 schema_class =&gt; '<strong>Foo::Schema</strong>',
52d980cb 750);
751
7521;</pre>
01b7b88c 753 <p>Keep your Schema in a <em>separate</em> package from your Catalyst application</p>
52d980cb 754 </div>
755
756 <div class="slide">
757 <h1>Catalyst</h1>
758<pre>sub action_name : Local {
759 my ($self, $c) = @_;
760
01b7b88c 761 my $schema = $c-&gt;model('Schema::Foo');
762 my $author_rs = $schema-&gt;resultset('Authors');
52d980cb 763
764}
765
7661;</pre>
767 </div>
768
769</div>
770</body>
771</html>