DBIx::Class beginners
-
Upload
leo-lapworth -
Category
Technology
-
view
48.092 -
download
1
description
Transcript of DBIx::Class beginners
![Page 1: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/1.jpg)
DBIx::Class (aka DBIC)for (advanced) beginners
Leo Lapworth @ LPW 2008
http://leo.cuckoo.org/projects/
![Page 2: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/2.jpg)
assumptions
You know a little about Perl and using objects
You know a little bit about databases and using foreign keys
![Page 3: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/3.jpg)
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)
![Page 4: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/4.jpg)
why this talk?
• Help avoid mistakes I made!
• Help learn DBIx::Class faster
• Make your coding easier
![Page 5: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/5.jpg)
point of note
"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." - Brian W. Kernighan
This talk is about making it easy so we you are less
likely to get confused
![Page 6: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/6.jpg)
table setup
![Page 7: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/7.jpg)
example...
Books
Authors
![Page 8: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/8.jpg)
authors table
CREATE TABLE authors(
id int(8) primary key auto_increment,
name varchar(255)
) engine = InnoDB DEFAULT CHARSET=utf8;
![Page 9: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/9.jpg)
tips
Name tables as simple plurals (add an S) - makes relationships easier to understand
(issue: Matt Trout "Tables should not be plural as gives you plurals for Result:: package names which represent a single row" - 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)
![Page 10: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/10.jpg)
authors table
CREATE TABLE authors(
id int(8) primary key auto_increment,
name varchar(255)
) engine = InnoDB DEFAULT CHARSET=utf8;
![Page 11: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/11.jpg)
books tableCREATE 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;
![Page 12: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/12.jpg)
tips
Name link fields as singular
Check foreign key is the same field type and size in both tables
![Page 13: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/13.jpg)
books tableCREATE 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;
![Page 14: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/14.jpg)
CRUD comparedC - CreateR - RetrieveU - UpdateD - Delete
![Page 15: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/15.jpg)
Manual (SQL)
![Page 16: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/16.jpg)
manual: createmy $sth = $dbh->prepare('
INSERT INTO books
(title, author)
values (?,?)
');
$sth->execute( 'A book title',$author_id);
![Page 17: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/17.jpg)
manual: createmy $sth = $dbh->prepare('
INSERT INTO books
(title, author)
values (?,?)
');
$sth->execute(
'A book title',$author_id);
![Page 18: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/18.jpg)
manual: retrievemy $sth = $dbh->prepare('
SELECT title,
authors.name as author_name
FROM books, authors
WHERE books.author = authors.id
');
![Page 19: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/19.jpg)
manual: retrievewhile( my $book = $sth->fetchrow_hashref() ) {
print 'Author of '
. $book->{title}
. ' is '
. $book->{author_name}
. "\n";
}
![Page 20: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/20.jpg)
manual: updatemy $update = $dbh->prepare('
UPDATE books
SET title = ?
WHERE id = ?
');
$update->execute(
'New title',$book_id);
![Page 21: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/21.jpg)
manual: deletemy $delete = $dbh->prepare('
DELETE FROM books
WHERE id = ?
');
$delete->execute($book_id);
![Page 22: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/22.jpg)
DBIx::Class
![Page 23: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/23.jpg)
DBIC: createmy $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.
![Page 24: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/24.jpg)
DBIC: createmy $book = $book_model->create({
title => 'A book title',
author => $author_id,});
![Page 25: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/25.jpg)
DBIC: createmy $pratchett = $author_model->create({
name => 'Terry Pratchett',
});
![Page 26: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/26.jpg)
DBIC: createmy $book = $pratchett->create_related(
'books', {
title => 'Another Discworld book',
});
or
my $book = $pratchett->add_to_books({
title => 'Another Discworld book',
});
![Page 27: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/27.jpg)
DBIC: createmy $book = $pratchett->create_related(
'books', {
title => 'Another Discworld book',
});
or
my $book = $pratchett->add_to_books({
title => 'Another Discworld book',
});
![Page 28: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/28.jpg)
DBIC: retrieve
DBIx::Class - Lots of ways to do the same thing...
"There is more than one way to do it (TIMTOWTDI, usually pronounced "Tim Toady") is a Perl motto"
![Page 29: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/29.jpg)
DBIC: retrievemy $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();
![Page 30: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/30.jpg)
DBIC: retrievewhile( my $book = $books_rs->next() ) {
print 'Author of '
. $book->title()
. ' is '
. $book->author()->name()
. "\n";
}
![Page 31: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/31.jpg)
DBIC: retrievemy $books_rs = $book_model->search({
author => $author_id,
});
Search takes SQL::Abstract formatted queries> perldoc SQL::Abstract
![Page 32: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/32.jpg)
DBIC: update$book->update({
title => 'New title',
});
![Page 33: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/33.jpg)
DBIC: delete$book->delete();
![Page 34: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/34.jpg)
Creating models
![Page 35: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/35.jpg)
![Page 36: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/36.jpg)
![Page 37: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/37.jpg)
too much typing!
too much maintenance!
![Page 38: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/38.jpg)
Schema::Loader
Tip
LPW::DBIC::Result::XXLPW::DBIC::ResultSet::XX
![Page 39: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/39.jpg)
splitting logic cleanly
LPW::DBIC::Result::XXX = an individual row
LPW::DBIC::ResultSet::XXX = searches / results
![Page 40: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/40.jpg)
using your Schema
![Page 41: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/41.jpg)
DEBUGGING
DBIC_TRACE=1 ./your_script.pl
![Page 42: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/42.jpg)
Schema::LoaderLPW::DBIC::Result::Authors->table("authors");LPW::DBIC::Result::Authors->add_columns( "id", { data_type => "INT", default_value => undef, is_nullable => 0, size => 8 }, "title", { data_type => "VARCHAR", default_value => undef, is_nullable => 1, size => 255, },);LPW::DBIC::Result::Authors->set_primary_key("id");
![Page 43: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/43.jpg)
LPW::DBIC::Result::Books->table("books");LPW::DBIC::Result::Books->add_columns( "id", { data_type => "INT", default_value => undef, is_nullable => 0, size => 8 }, "name", { data_type => "VARCHAR", default_value => undef, is_nullable => 1, size => 255, }, "author", { data_type => "INT", default_value => undef, is_nullable => 1, size => 8 },);LPW::DBIC::Result::Books->set_primary_key("id");
Schema::Loader
![Page 44: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/44.jpg)
LPW::DBIC::Result::Authors->has_many("books", "LPW::DBIC::Books", { "foreign.author" => "self.id" });
LPW::DBIC::Result::Books->belongs_to("author", "LPW::DBIC::Authors", { id => "author" });
Schema::Loader
![Page 45: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/45.jpg)
Schema::Loader
![Page 46: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/46.jpg)
SQL - debugging
INSERT INTO authors (name) VALUES (?): 'Douglas Adams'
INSERT INTO books (author, title) VALUES (?, ?): '5', '42'
![Page 47: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/47.jpg)
overloading
LPW::DBIC::Result::Books
LPW:: DBIC::ResultSet::Books
LPW:: DBIC::Result::Authors
LPW:: DBIC::ResultSet::Authors
![Page 48: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/48.jpg)
Result::package LPW::DBIC::Result::Books;use base 'DBIx::Class';
use strict;use warnings;
sub isbn {my $self = shift;
# search amazon or somethingmy $api = Amazon::API->book({ title => $self->title() });
return $api->isbn();}
1;
![Page 49: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/49.jpg)
Result::package LPW::DBIC::Result::Books;use base 'DBIx::Class';
use strict;use warnings;
sub isbn {my $self = shift;
# search amazon or somethingmy $api = Amazon::API->book({ title => $self->title() });
return $api->isbn();}
1;
![Page 50: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/50.jpg)
Result::print $book->isbn();
![Page 51: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/51.jpg)
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
![Page 52: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/52.jpg)
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
![Page 53: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/53.jpg)
Result:: (deflating)$book->date_published(DateTime->now);
$book->update();
2008-11-29
![Page 54: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/54.jpg)
Result:: (inflating)my $date_published = $book->date_published()print $date_published->month_abbr();
Nov
![Page 55: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/55.jpg)
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;
![Page 56: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/56.jpg)
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(), } );}
![Page 57: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/57.jpg)
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;
![Page 58: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/58.jpg)
ResultSets::use LPW::DBIC;
my $book_model = LPW::DBIC->resultset('Books');
my $book_rs = $book_model->the_ultimate_books();
my @books = $book_rs->all();
![Page 59: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/59.jpg)
ResultSets::chaininguse 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();
![Page 60: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/60.jpg)
ResultSets::chainingmy $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%'
![Page 61: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/61.jpg)
ResultSets::chainingmy $rs = $book_model
->category('childrens') ->by_author($author) ->published_after('1812') ->first_page_contains('once upon') ->rating_greater_than(4);
my @books = $rs->all();
![Page 62: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/62.jpg)
overloading before new record
![Page 63: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/63.jpg)
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;
![Page 64: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/64.jpg)
relationships
![Page 65: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/65.jpg)
multiple authors
![Page 66: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/66.jpg)
a few relationships
Authors BooksAuthors_and_Books
has_many has_many
belongs_to belongs_to
many_to_many
![Page 67: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/67.jpg)
a few relationships
!
![Page 68: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/68.jpg)
new join tableCREATE 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`
![Page 69: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/69.jpg)
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;
new join table
![Page 70: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/70.jpg)
has_many
Books Authors_and_Books
has_many
belongs_to
![Page 71: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/71.jpg)
has_manypackage LPW::DBIC::Result::Books;
__PACKAGE__->has_many(
"author_and_books", "LPW::DBIC::Result::AuthorAndBooks",
{ "foreign.book" => "self.id" },
);
# This is auto generated by Schema::Loader
![Page 72: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/72.jpg)
has_manypackage LPW::DBIC::Result::Books;
__PACKAGE__->has_many(
"author_and_books", # Name of accessor "LPW::DBIC::Result::AuthorAndBooks", # Related class { "foreign.book" => "self.id" }, # Relationship (magic often works if not # specified, but avoid!));
![Page 73: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/73.jpg)
belongs_to
Books Authors_and_Books
has_many
belongs_to
![Page 74: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/74.jpg)
belongs_topackage LPW::DBIC::Result::AuthorAndBooks;
__PACKAGE__->belongs_to( "book", "LPW::DBIC::Result::Books", { id => "book" });
# This is auto generated by Schema::Loader
![Page 75: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/75.jpg)
belongs_topackage LPW::DBIC::Result::AuthorAndBooks;
__PACKAGE__->belongs_to( "book", # Accessor name "LPW::DBIC::Result::Books", # Related class { id => "book" } # Relationship);
![Page 76: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/76.jpg)
same for Authors
Authors Authors_and_Books
has_many
belongs_to
![Page 77: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/77.jpg)
with no coding...
Authors BooksAuthors_and_Books
has_many has_many
belongs_to belongs_to
![Page 78: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/78.jpg)
many_to_many
Authors BooksAuthors_and_Books
has_many has_many
belongs_to belongs_to
many_to_many
![Page 79: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/79.jpg)
many_to_manypackage LPW::DBIC::Result::Books;use base 'DBIx::Class';
__PACKAGE__->many_to_many( "authors"
=> "author_and_books",
'author');
1;
# This is NOT auto generated by Schema::Loader
![Page 80: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/80.jpg)
many_to_manypackage LPW::DBIC::Result::Books;use base 'DBIx::Class';
__PACKAGE__->many_to_many( "authors" # Accessor Name => "author_and_books", # has_many accessor_name 'author' # foreign relationship name);
1;
![Page 81: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/81.jpg)
many_to_manypackage LPW::DBIC::Result::Authors;use base 'DBIx::Class';
__PACKAGE__->many_to_many( "books" # Accessor Name => "author_and_books", # has_many accessor_name 'book' # foreign relationship name);
1;
# This is NOT auto generated by Schema::Loader
![Page 82: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/82.jpg)
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',
});
![Page 83: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/83.jpg)
using many_to_manymy $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';
![Page 84: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/84.jpg)
using many_to_many$author->add_to_books($book);
$book->add_to_authors($author_1);
$book->add_to_authors($author_2);
![Page 85: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/85.jpg)
in 16 lines of code
Authors BooksAuthors_and_Books
has_many has_many
belongs_to belongs_to
many_to_many
![Page 86: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/86.jpg)
errors
Read them closely!
![Page 87: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/87.jpg)
error messagesDBIx::Class::Schema::Loader::connection(): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method "many_to_many" via package "LPW::DBIC::Result::Author" 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.
![Page 88: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/88.jpg)
error messagesDBIx::Class::Schema::Loader::connection(): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method "many_to_many" via package "LPW::DBIC::Result::Author" 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.
![Page 89: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/89.jpg)
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
![Page 90: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/90.jpg)
thanks
http://leo.cuckoo.org/projects/
Time for bonus slides?
![Page 91: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/91.jpg)
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
![Page 92: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/92.jpg)
Catalystpackage Your::App::Model::LPW;use base qw(Catalyst::Model::DBIC::Schema);
use strict;use warnings;
__PACKAGE__->config( schema_class => 'LPW::DBIC',);
1;
![Page 93: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/93.jpg)
Catalystpackage 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
![Page 94: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/94.jpg)
Catalystsub action_name : Local { my ($self, $c) = @_;
my $model = $c->model('DBIC::LPW'); my $author_model = $model->resultset('Authors'); }
1;
![Page 95: DBIx::Class beginners](https://reader034.fdocuments.net/reader034/viewer/2022042623/54851b17b47959d80c8b4d3b/html5/thumbnails/95.jpg)
thanks!
http://leo.cuckoo.org/projects/