Class::DBIは、いろんな意味で最高なのですが、many_to_manyのリレーションを作るどうやればいいんだろうなぁ。と、いろいろ検索して、見つけたのが、ξ;゜ー゜)ξ { 遅レス。 - Class::DBI(CDBI)で多対多(many_to_many)。
そういえば、大昔、というか、前の(?)会社の時に、先輩が、そういう風にテーブルを作っていたなぁ、と懐かしくなったりしつつ、いろいろ利用。ところが、なんかうまくいかないです。
結論から言うと、Complex many to many - ClassDBIのように、中間テーブルには、idカラムというか、「複合ではないプライマリキー」が必要でした。
リンク先の例にならうと、
CREATE TABLE Users (
code varchar(8) primary key,
passwd varchar(255) not null
);
CREATE TABLE CourseUsers (
id varchar(8) primary key,
user_code varchar(8) not null,
course_code varchar(255) not null,
unique (user_code, course_code)
);
CREATE TABLE Courses (
code varchar(5) primary key,
name varchar(255) not null
);
package MyApp::Model::CDBI;
use strict;
use base 'Class::DBI::SQLite';
__PACKAGE__->set_db('Main', 'dbi:SQLite:dbname=/path/to/dbfile');
package MyApp::Model::CDBI::Users;
use strict;
use base 'MyApp::Model::CDBI';
__PACKAGE__->set_up_table('Users');
__PACKAGE__->has_many(courses => ["MyApp::Model::CDBI::CourseUsers" => 'course_code'], 'user_code');
package MyApp::Model::CDBI::CourseUsers;
use strict;
use base 'MyApp::Model::CDBI';
__PACKAGE__->set_up_table('CourseUsers');
__PACKAGE__->has_a(course_code => "MyApp::Model::CDBI::Courses");
__PACKAGE__->has_a(user_code => "MyApp::Model::CDBI::Users");
sub courses { shift->user->courses }
sub users { shift->course->users }
package MyApp::Model::CDBI::Courses;
use strict;
use base 'MyApp::Model::CDBI';
__PACKAGE__->set_up_table('Courses');
__PACKAGE__->has_many(users => ["MyApp::Model::CDBI::CourseUsers" => 'user_code'], 'course_code');
たぶん、こんな感じ。
なんというか、結局のところ、本家の情報を英語だからといって避けたりしないでちゃんと読め。ってことなんだろうなぁ……
コメント