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');
たぶん、こんな感じ。
なんというか、結局のところ、本家の情報を英語だからといって避けたりしないでちゃんと読め。ってことなんだろうなぁ……