DBIx::Class (aka DBIC)
      for (advanced) beginners



     Leo Lapworth @ LPW 2008

    http://leo.cuckoo.org/projects/
assumptions

   You know a little about Perl
   and using objects

   You know a little bit about
   databases and using f...
DBIx::Class?
•   ORM (object relational mapper)

•   SQL <-> OO (using objects instead of SQL)

•   Simple, powerful, comp...
why this talk?
• Help avoid mistakes I made!
• Help learn DBIx::Class faster
• Make your coding easier
point of note
quot;Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as c...
table setup
example...

Books




Authors
authors table

CREATE TABLE authors(

 id     int(8) primary key auto_increment,

 name   varchar(255)

) engine = InnoDB ...
tips

Name tables as simple plurals (add an S) -
makes relationships easier to understand
(issue: Matt Trout quot;Tables s...
authors table

CREATE TABLE author   s(
 id     int(8) primary key auto_increment,

 name   varchar(255)

) engine =   Inn...
books table
CREATE TABLE books(

 id      int(8) primary key auto_increment,

 title   varchar(255),

 author int(8),

 fo...
tips


Name link fields as singular


Check foreign key is the same field type and
size in both tables
books table
CREATE TABLE books(
 id      int(8) primary key auto_increment,
 title   varchar(255),
 author int(8),

 forei...
CRUD compared
    C - Create
    R - Retrieve
    U - Update
    D - Delete
Manual (SQL)
manual: create
my $sth = $dbh->prepare('
 INSERT INTO books
 (title, author)
 values (?,?)
');


$sth->execute(
   'A book...
manual: create
my $sth = $dbh->prepare('
 INSERT INTO books
 (title, author)
 values (?,?)
');


$sth->execute(
     'A bo...
manual: retrieve
my $sth = $dbh->prepare('
  SELECT title,
  authors.name as author_name
  FROM books, authors
  WHERE boo...
manual: retrieve
while( my $book = $sth->fetchrow_hashref() )
{
    print 'Author of '
        . $book->{title}
       . '...
manual: update
my $update = $dbh->prepare('
 UPDATE books
 SET title = ?
 WHERE id = ?
');


$update->execute(
  'New titl...
manual: delete
my $delete = $dbh->prepare('
 DELETE FROM books
 WHERE id = ?
');


$delete->execute(   $book_id);
DBIx::Class
DBIC: create
my $book = $book_model->create({
 title => 'A book title',
 author => $author_id,
});

Look ma, no SQL!

Tip:...
DBIC: create
my $book = $book_model->create({
 title => 'A book title',

 author =>   $author_id,
});
DBIC: create
my $pratchett = $author_model->create({
  name => 'Terry Pratchett',
});
DBIC: create
my $book = $pratchett->create_related(
  'books', {
      title => 'Another Discworld book',
});
or
my $book ...
DBIC: create
my $book = $pratchett->create_related(
  'books', {
      title => 'Another Discworld book',
});
or
my $book ...
DBIC: retrieve

DBIx::Class - Lots of ways to do the same thing...

quot;There is more than one way to do it (TIMTOWTDI,
u...
DBIC: retrieve
my $book = $book_model->find($book_id);


my $book = $book_model->search({
 title => 'A book title',
})->si...
DBIC: retrieve
while( my $book = $books_rs->next() ) {
    print 'Author of '
        . $book->title()
       . ' is '
   ...
DBIC: retrieve
my $books_rs = $book_model->search({
 author => $author_id,
});




Search takes SQL::Abstract formatted qu...
DBIC: update
$book->update({
  title => 'New title',
});
DBIC: delete
$book->delete();
Creating models
too much
   typing!

  too much
maintenance!
Schema::Loader



                       Tip


         LPW::DBIC::Result::XX
         LPW::DBIC::ResultSet::XX
splitting logic
      cleanly

LPW::DBIC::Result::XXX     = an individual row

LPW::DBIC::ResultSet::XXX = searches / resu...
using your Schema
DEBUGGING
DBIC_TRACE=1 ./your_script.pl
Schema::Loader
LPW::DBIC::Result::Authors->table(quot;authorsquot;);
LPW::DBIC::Result::Authors->add_columns(
   quot;idqu...
Schema::Loader
LPW::DBIC::Result::Books->table(quot;booksquot;);
LPW::DBIC::Result::Books->add_columns(
   quot;idquot;,
 ...
Schema::Loader
LPW::DBIC::Result::Authors->has_many(quot;booksquot;, quot;LPW::DBIC::Booksquot;,
{ quot;foreign.authorquot...
Schema::Loader
SQL - debugging

INSERT INTO authors (name)
      VALUES (?): 'Douglas Adams'


INSERT INTO books (author, title)
      VA...
overloading

LPW::DBIC::Result::Books
LPW:: DBIC::ResultSet::Books
LPW:: DBIC::Result::Authors
LPW:: DBIC::ResultSet::Auth...
Result::
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

use strict;
use warnings;

sub isbn {
  my $self = shi...
Result::
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

use strict;
use warnings;

sub isbn {
  my $self = shi...
Result::
print $book->isbn();
Result:: (inflating)
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

use strict;
use warnings;
use DateTime::Fo...
Result:: (inflating)
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

use strict;
use warnings;
use DateTime::Fo...
Result:: (deflating)
$book->date_published(DateTime->now);

$book->update();




                                        2...
Result:: (inflating)
my $date_published = $book->date_published()
print $date_published->month_abbr();




               ...
ResultSets::
package LPW::DBIC::ResultSet::Books;
use base 'DBIx::Class::ResultSet';

sub the_ultimate_books {
    my $sel...
ResultSets::
package LPW::DBIC::ResultSet::Books;
use base 'DBIx::Class::ResultSet';
sub the_ultimate_books {
    my $self...
ResultSets::
package LPW::DBIC::ResultSet::Books;
use base 'DBIx::Class::ResultSet';

sub the_ultimate_books {
    my $sel...
ResultSets::
use LPW::DBIC;

my $book_model   = LPW::DBIC->resultset('Books');

my $book_rs      = $book_model->the_ultima...
ResultSets::chaining
use LPW::DBIC;

my $book_model   = LPW::DBIC->resultset('Books');
my $author_model = LPW::DBIC->resul...
ResultSets::chaining
my $book_rs = $book_model
               ->the_ultimate_books()
               ->by_author($author);
...
ResultSets::chaining
my $rs = $book_model
            ->category('childrens')
            ->by_author($author)
           ...
overloading before
    new record
overloading before
        new record
package LPW::DBIC::Result::Authors;
use base 'DBIx::Class';

sub new {
    my ( $cla...
relationships
multiple authors
a few relationships
     has_many                has_many

Authors         Authors_and_Books       Books


    belongs_to ...
a few relationships



        !
new join table
CREATE TABLE author_and_books(
    id      int(8)    primary key auto_increment,
    book 
 int(8),
    aut...
new join table
CREATE TABLE author_and_books(
    id      int(8)    primary key auto_increment,
    book 
 int(8),
    aut...
has_many
        has_many


Books           Authors_and_Books




        belongs_to
has_many
package LPW::DBIC::Result::Books;

__PACKAGE__->has_many(

     quot;author_and_booksquot;,

     quot;LPW::DBIC:...
has_many
package LPW::DBIC::Result::Books;

__PACKAGE__->has_many(

     quot;author_and_booksquot;,
        # Name of acc...
belongs_to
        has_many


Books           Authors_and_Books




        belongs_to
belongs_to
package LPW::DBIC::Result::AuthorAndBooks;


__PACKAGE__->belongs_to(
    quot;bookquot;,
    quot;LPW::DBIC::R...
belongs_to
package LPW::DBIC::Result::AuthorAndBooks;


__PACKAGE__->belongs_to(
    quot;bookquot;,                     #...
same for Authors

     has_many

Authors         Authors_and_Books



    belongs_to
with no coding...

     has_many                has_many

Authors         Authors_and_Books       Books


    belongs_to  ...
many_to_many

     has_many                has_many

Authors         Authors_and_Books       Books


    belongs_to       ...
many_to_many
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

__PACKAGE__->many_to_many(
    quot;authorsquot;

...
many_to_many
package LPW::DBIC::Result::Books;
use base 'DBIx::Class';

__PACKAGE__->many_to_many(
    quot;authorsquot;
 ...
many_to_many
package LPW::DBIC::Result::Authors;
use base 'DBIx::Class';

__PACKAGE__->many_to_many(
    quot;booksquot;
 ...
using many_to_many
#!/usr/bin/perl

use LPW::DBIC;

my $author_model = LPW::DBIC->resultset('Authors');

my $author = $aut...
using many_to_many
my $author = $author_model->search({
  name => 'Douglas Adams',
})->single();

$author->add_to_books({
...
using many_to_many
$author->add_to_books($book);


$book->add_to_authors($author_1);

$book->add_to_authors($author_2);
in 16 lines of code
     has_many                has_many

Authors         Authors_and_Books       Books


    belongs_to ...
errors


 Read them closely!
error messages
DBIx::Class::Schema::Loader::connection
(): Failed to load external class
definition for
'LPW::DBIC::Result...
error messages
DBIx::Class::Schema::Loader::connection
(): Failed to load external class
definition for
'LPW::DBIC::Result...
errors

• Turn on debugging
• Read error messages (sometimes useful!)
• Check field names
• Check package names
• Check whi...
thanks

http://leo.cuckoo.org/projects/

    Time for bonus slides?
Template Toolkit


• [% author.books.count %] not working?
• TT all methods are called in list context
• [% author.books_r...
Catalyst
package Your::App::Model::LPW;
use base qw(Catalyst::Model::DBIC::Schema);

use strict;
use warnings;

__PACKAGE_...
Catalyst
package Your::App::Model::LPW;
use base qw(Catalyst::Model::DBIC::Schema);

use strict;
use warnings;

__PACKAGE_...
Catalyst
sub action_name : Local {
  my ($self, $c) = @_;

     my $model = $c->model('DBIC::LPW');
     my $author_model ...
thanks!


http://leo.cuckoo.org/projects/
DBIx::Class beginners
DBIx::Class beginners
Upcoming SlideShare
Loading in...5
×

DBIx::Class beginners

42,338

Published on

Introduction to DBIx::Class.

4 Comments
32 Likes
Statistics
Notes
No Downloads
Views
Total Views
42,338
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
805
Comments
4
Likes
32
Embeds 0
No embeds

No notes for slide

DBIx::Class beginners

  1. 1. DBIx::Class (aka DBIC) for (advanced) beginners Leo Lapworth @ LPW 2008 http://leo.cuckoo.org/projects/
  2. 2. assumptions You know a little about Perl and using objects You know a little bit about databases and using foreign keys
  3. 3. DBIx::Class? • ORM (object relational mapper) • SQL <-> OO (using objects instead of SQL) • Simple, powerful, complex, fab and confusing • There are many ORMs, DBIx::Class just happens to be the best in Perl (personal opinion)
  4. 4. why this talk? • Help avoid mistakes I made! • Help learn DBIx::Class faster • Make your coding easier
  5. 5. point of note quot;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.quot; - Brian W. Kernighan This talk is about making it easy so we you are less likely to get confused
  6. 6. table setup
  7. 7. example... Books Authors
  8. 8. authors table CREATE TABLE authors( id int(8) primary key auto_increment, name varchar(255) ) engine = InnoDB DEFAULT CHARSET=utf8;
  9. 9. tips Name tables as simple plurals (add an S) - makes relationships easier to understand (issue: Matt Trout quot;Tables should not be plural as gives you plurals for Result:: package names which represent a single rowquot; - talk may be rewritten in future to reflect this as this is better once you understand the relationship setup - either way, consistency is important) Use a character set (UTF8) from the start (for international characters)
  10. 10. authors table CREATE TABLE author s( id int(8) primary key auto_increment, name varchar(255) ) engine = InnoDB DEFAULT CHARSET= utf8;
  11. 11. books table CREATE TABLE books( id int(8) primary key auto_increment, title varchar(255), author int(8), foreign key (author) references authors(id) ) engine = InnoDB DEFAULT CHARSET=utf8;
  12. 12. tips Name link fields as singular Check foreign key is the same field type and size in both tables
  13. 13. books table CREATE TABLE books( id int(8) primary key auto_increment, title varchar(255), author int(8), foreign key ( author) references authors(id) ) engine = InnoDB DEFAULT CHARSET=utf8;
  14. 14. CRUD compared C - Create R - Retrieve U - Update D - Delete
  15. 15. Manual (SQL)
  16. 16. manual: create my $sth = $dbh->prepare(' INSERT INTO books (title, author) values (?,?) '); $sth->execute( 'A book title',$author_id );
  17. 17. manual: create my $sth = $dbh->prepare(' INSERT INTO books (title, author) values (?,?) '); $sth->execute( 'A book title', $author_id );
  18. 18. manual: retrieve my $sth = $dbh->prepare(' SELECT title, authors.name as author_name FROM books, authors WHERE books.author = authors.id ');
  19. 19. manual: retrieve while( my $book = $sth->fetchrow_hashref() ) { print 'Author of ' . $book->{title} . ' is ' . $book->{author_name} . quot;nquot;; }
  20. 20. manual: update my $update = $dbh->prepare(' UPDATE books SET title = ? WHERE id = ? '); $update->execute( 'New title', $book_id);
  21. 21. manual: delete my $delete = $dbh->prepare(' DELETE FROM books WHERE id = ? '); $delete->execute( $book_id);
  22. 22. DBIx::Class
  23. 23. DBIC: create my $book = $book_model->create({ title => 'A book title', author => $author_id, }); Look ma, no SQL! Tip: do not pass in primary_key field, even if its empty/undef as the object returned will have an empty id, even if your field is auto increment.
  24. 24. DBIC: create my $book = $book_model->create({ title => 'A book title', author => $author_id, });
  25. 25. DBIC: create my $pratchett = $author_model->create({ name => 'Terry Pratchett', });
  26. 26. DBIC: create my $book = $pratchett->create_related( 'books', { title => 'Another Discworld book', }); or my $book = $pratchett->add_to_books({ title => 'Another Discworld book', });
  27. 27. DBIC: create my $book = $pratchett->create_related( 'books', { title => 'Another Discworld book', }); or my $book = $pratchett->add_to_books({ title => 'Another Discworld book', });
  28. 28. DBIC: retrieve DBIx::Class - Lots of ways to do the same thing... quot;There is more than one way to do it (TIMTOWTDI, usually pronounced quot;Tim Toadyquot;) is a Perl mottoquot;
  29. 29. DBIC: retrieve my $book = $book_model->find($book_id); my $book = $book_model->search({ title => 'A book title', })->single(); my @books = $book_model->search({ author => $author_id, })->all();
  30. 30. DBIC: retrieve while( my $book = $books_rs->next() ) { print 'Author of ' . $book->title() . ' is ' . $book->author()->name() . quot;nquot;; }
  31. 31. DBIC: retrieve my $books_rs = $book_model->search({ author => $author_id, }); Search takes SQL::Abstract formatted queries > perldoc SQL::Abstract
  32. 32. DBIC: update $book->update({ title => 'New title', });
  33. 33. DBIC: delete $book->delete();
  34. 34. Creating models
  35. 35. too much typing! too much maintenance!
  36. 36. Schema::Loader Tip LPW::DBIC::Result::XX LPW::DBIC::ResultSet::XX
  37. 37. splitting logic cleanly LPW::DBIC::Result::XXX = an individual row LPW::DBIC::ResultSet::XXX = searches / results
  38. 38. using your Schema
  39. 39. DEBUGGING DBIC_TRACE=1 ./your_script.pl
  40. 40. Schema::Loader LPW::DBIC::Result::Authors->table(quot;authorsquot;); LPW::DBIC::Result::Authors->add_columns( quot;idquot;, { data_type => quot;INTquot;, default_value => undef, is_nullable => 0, size => 8 }, quot;titlequot;, { data_type => quot;VARCHARquot;, default_value => undef, is_nullable => 1, size => 255, }, ); LPW::DBIC::Result::Authors->set_primary_key(quot;idquot;);
  41. 41. Schema::Loader LPW::DBIC::Result::Books->table(quot;booksquot;); LPW::DBIC::Result::Books->add_columns( quot;idquot;, { data_type => quot;INTquot;, default_value => undef, is_nullable => 0, size => 8 }, quot;namequot;, { data_type => quot;VARCHARquot;, default_value => undef, is_nullable => 1, size => 255, }, quot;authorquot;, { data_type => quot;INTquot;, default_value => undef, is_nullable => 1, size => 8 }, ); LPW::DBIC::Result::Books->set_primary_key(quot;idquot;);
  42. 42. Schema::Loader LPW::DBIC::Result::Authors->has_many(quot;booksquot;, quot;LPW::DBIC::Booksquot;, { quot;foreign.authorquot; => quot;self.idquot; }); LPW::DBIC::Result::Books->belongs_to(quot;authorquot;, quot;LPW::DBIC::Authorsquot;, { id => quot;authorquot; });
  43. 43. Schema::Loader
  44. 44. SQL - debugging INSERT INTO authors (name) VALUES (?): 'Douglas Adams' INSERT INTO books (author, title) VALUES (?, ?): '5', '42'
  45. 45. overloading LPW::DBIC::Result::Books LPW:: DBIC::ResultSet::Books LPW:: DBIC::Result::Authors LPW:: DBIC::ResultSet::Authors
  46. 46. Result:: package LPW::DBIC::Result::Books; use base 'DBIx::Class'; use strict; use warnings; sub isbn { my $self = shift; # search amazon or something my $api = Amazon::API->book({ title => $self->title() }); return $api->isbn(); } 1;
  47. 47. Result:: package LPW::DBIC::Result::Books; use base 'DBIx::Class'; use strict; use warnings; sub isbn { my $self = shift; # search amazon or something my $api = Amazon::API->book({ title => $self->title() }); return $api->isbn(); } 1;
  48. 48. Result:: print $book->isbn();
  49. 49. Result:: (inflating) package LPW::DBIC::Result::Books; use base 'DBIx::Class'; use strict; use warnings; use DateTime::Format::MySQL; __PACKAGE__->inflate_column( 'date_published', { inflate => sub { DateTime::Format::MySQL->parse_date(shift); }, deflate => sub { shift->ymd(); }, } ); # Automatic see: DBIx::Class::InflateColumn::DateTime
  50. 50. Result:: (inflating) package LPW::DBIC::Result::Books; use base 'DBIx::Class'; use strict; use warnings; use DateTime::Format::MySQL; __PACKAGE__->inflate_column( 'date_published', { inflate => sub { DateTime::Format::MySQL->parse_date(shift); }, deflate => sub { shift->ymd(); }, } ); # Automatic see: DBIx::Class::InflateColumn::DateTime
  51. 51. Result:: (deflating) $book->date_published(DateTime->now); $book->update(); 2008-11-29
  52. 52. Result:: (inflating) my $date_published = $book->date_published() print $date_published->month_abbr(); Nov
  53. 53. ResultSets:: package LPW::DBIC::ResultSet::Books; use base 'DBIx::Class::ResultSet'; sub the_ultimate_books { my $self = shift; return $self->search( { title => { 'like', '%42%' } }); } sub by_author { my ( $self, $author ) = @_; return $self->search( { author => $author->id(), } ); } 1;
  54. 54. ResultSets:: package LPW::DBIC::ResultSet::Books; use base 'DBIx::Class::ResultSet'; sub the_ultimate_books { my $self = shift; return $self->search( { title => { 'like', '%42%' } }); } sub by_author { my ( $self, $author ) = @_; return $self->search( { author => $author->id(), } ); }
  55. 55. ResultSets:: package LPW::DBIC::ResultSet::Books; use base 'DBIx::Class::ResultSet'; sub the_ultimate_books { my $self = shift; return $self->search( { title => { 'like', '%42%' } }); } sub by_author { my ( $self, $author ) = @_; return $self->search( { author => $author->id(), } ); }
  56. 56. ResultSets:: use LPW::DBIC; my $book_model = LPW::DBIC->resultset('Books'); my $book_rs = $book_model->the_ultimate_books(); my @books = $book_rs->all();
  57. 57. ResultSets::chaining use LPW::DBIC; my $book_model = LPW::DBIC->resultset('Books'); my $author_model = LPW::DBIC->resultset('Authors'); my $author = $author_model->search({ name => 'Douglas Adams', })->single(); my $book_rs = $book_model->the_ultimate_books() ->by_author($author); my @books = $book_rs->all();
  58. 58. ResultSets::chaining my $book_rs = $book_model ->the_ultimate_books() ->by_author($author); or my $book_rs = $book_model ->the_ultimate_books(); $book_rs = $book_rs->by_author($author); # Debug (SQL): # SELECT me.id, me.title, me.date_published, me.author # FROM books me # WHERE ( ( ( author = ? ) AND ( title LIKE ? ) ) ): '5', '%42%'
  59. 59. ResultSets::chaining my $rs = $book_model ->category('childrens') ->by_author($author) ->published_after('1812') ->first_page_contains('once upon') ->rating_greater_than(4); my @books = $rs->all();
  60. 60. overloading before new record
  61. 61. overloading before new record package LPW::DBIC::Result::Authors; use base 'DBIx::Class'; sub new { my ( $class, $attrs ) = @_; # Mess with $attrs my $new = $class->next::method($attrs); return $new; } 1;
  62. 62. relationships
  63. 63. multiple authors
  64. 64. a few relationships has_many has_many Authors Authors_and_Books Books belongs_to belongs_to many_to_many
  65. 65. a few relationships !
  66. 66. new join table CREATE TABLE author_and_books( id int(8) primary key auto_increment, book int(8), author int(8), foreign key (book) references books(id), foreign key (author) references authors(id) ) engine = InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `books` DROP `author`
  67. 67. new join table CREATE TABLE author_and_books( id int(8) primary key auto_increment, book int(8), author int(8), foreign key (book) references books(id), foreign key (author) references authors(id) ) engine = InnoDB DEFAULT CHARSET=utf8;
  68. 68. has_many has_many Books Authors_and_Books belongs_to
  69. 69. has_many package LPW::DBIC::Result::Books; __PACKAGE__->has_many( quot;author_and_booksquot;, quot;LPW::DBIC::Result::AuthorAndBooksquot;, { quot;foreign.bookquot; => quot;self.idquot; }, ); # This is auto generated by Schema::Loader
  70. 70. has_many package LPW::DBIC::Result::Books; __PACKAGE__->has_many( quot;author_and_booksquot;, # Name of accessor quot;LPW::DBIC::Result::AuthorAndBooksquot;, # Related class { quot;foreign.bookquot; => quot;self.idquot; }, # Relationship (magic often works if not # specified, but avoid!) );
  71. 71. belongs_to has_many Books Authors_and_Books belongs_to
  72. 72. belongs_to package LPW::DBIC::Result::AuthorAndBooks; __PACKAGE__->belongs_to( quot;bookquot;, quot;LPW::DBIC::Result::Booksquot;, { id => quot;bookquot; } ); # This is auto generated by Schema::Loader
  73. 73. belongs_to package LPW::DBIC::Result::AuthorAndBooks; __PACKAGE__->belongs_to( quot;bookquot;, # Accessor name quot;LPW::DBIC::Result::Booksquot;, # Related class { id => quot;bookquot; } # Relationship );
  74. 74. same for Authors has_many Authors Authors_and_Books belongs_to
  75. 75. with no coding... has_many has_many Authors Authors_and_Books Books belongs_to belongs_to
  76. 76. many_to_many has_many has_many Authors Authors_and_Books Books belongs_to belongs_to many_to_many
  77. 77. many_to_many package LPW::DBIC::Result::Books; use base 'DBIx::Class'; __PACKAGE__->many_to_many( quot;authorsquot; => quot;author_and_booksquot;, 'author' ); 1; # This is NOT auto generated by Schema::Loader
  78. 78. many_to_many package LPW::DBIC::Result::Books; use base 'DBIx::Class'; __PACKAGE__->many_to_many( quot;authorsquot; # Accessor Name => quot;author_and_booksquot;, # has_many accessor_name 'author' # foreign relationship name ); 1;
  79. 79. many_to_many package LPW::DBIC::Result::Authors; use base 'DBIx::Class'; __PACKAGE__->many_to_many( quot;booksquot; # Accessor Name => quot;author_and_booksquot;, # has_many accessor_name 'book' # foreign relationship name ); 1; # This is NOT auto generated by Schema::Loader
  80. 80. using many_to_many #!/usr/bin/perl use LPW::DBIC; my $author_model = LPW::DBIC->resultset('Authors'); my $author = $author_model->search({ name => 'Douglas Adams', })->single(); $author->add_to_books({ title => 'A new book', });
  81. 81. using many_to_many my $author = $author_model->search({ name => 'Douglas Adams', })->single(); $author->add_to_books({ title => 'A new book', }); # SELECT me.id, me.name FROM authors me # WHERE ( name = ? ): 'Douglas Adams'; # INSERT INTO books (title) VALUES (?): 'A new book'; # INSERT INTO author_and_books (author, book) # VALUES (?, ?): '5', '2';
  82. 82. using many_to_many $author->add_to_books($book); $book->add_to_authors($author_1); $book->add_to_authors($author_2);
  83. 83. in 16 lines of code has_many has_many Authors Authors_and_Books Books belongs_to belongs_to many_to_many
  84. 84. errors Read them closely!
  85. 85. error messages DBIx::Class::Schema::Loader::connection (): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method quot;many_to_manyquot; via package quot;LPW::DBIC::Result::Authorquot; at lib/LPW/DBIC/Result/Authors.pm line 9. Compilation failed in require at / Library/Perl/5.8.8/DBIx/Class/Schema/ Loader/Base.pm line 292.
  86. 86. error messages DBIx::Class::Schema::Loader::connection (): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method quot;many_to_manyquot; via package quot;LPW::DBIC::Result::Authorquot; at lib/LPW/DBIC/Result/Authors.pm line 9. Compilation failed in require at / Library/Perl/5.8.8/DBIx/Class/Schema/ Loader/Base.pm line 292.
  87. 87. errors • Turn on debugging • Read error messages (sometimes useful!) • Check field names • Check package names • Check which database you are connected to (development/test/live?) - repeat above
  88. 88. thanks http://leo.cuckoo.org/projects/ Time for bonus slides?
  89. 89. Template Toolkit • [% author.books.count %] not working? • TT all methods are called in list context • [% author.books_rs.count %] scalar context Available for all relationships
  90. 90. Catalyst package Your::App::Model::LPW; use base qw(Catalyst::Model::DBIC::Schema); use strict; use warnings; __PACKAGE__->config( schema_class => 'LPW::DBIC', ); 1;
  91. 91. Catalyst package Your::App::Model::LPW; use base qw(Catalyst::Model::DBIC::Schema); use strict; use warnings; __PACKAGE__->config( schema_class => 'LPW::DBIC', ); 1; Keep your Scheme in a separate package to your Catalyst application
  92. 92. Catalyst sub action_name : Local { my ($self, $c) = @_; my $model = $c->model('DBIC::LPW'); my $author_model = $model->resultset('Authors'); } 1;
  93. 93. thanks! http://leo.cuckoo.org/projects/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×