DBIx::MoCoと格闘中
DBIx::MoCo触り中。基本的な使い方は分かったが、joinが色々分からない。
いつも通りdbはrailsのマイグレーションで作成。アプリはcatalystで。
ただ今回、行き詰まったのでアプリ使う意味が(まだ)無い。
http://github.com/hirafoo/moco_training/tree/master
DB
親と子と孫。
Oya has_many Ko
Ko has_many Mago
これ以上の説明は不要だよね。
加えて、KoとOyaをjoinするためのクラス、KoOyaを作成。
joinするには、DBIx::MoCo::Joinを継承したクラスを作るようなので。KoOyaというテーブルが存在するわけではない。
あと他の方法でもjoin可。
package Moco::Model::KoOya; use base qw/DBIx::MoCo::Join Moco::Model::Ko Moco::Model::Oya/; use Moco::Utils; use Moco::Model::DataBase; __PACKAGE__->db_object('Moco::Model::DataBase'); #__PACKAGE__->table('ko INNER JOIN oya ON ko.oya_id = oya.oya_p'); __PACKAGE__->table('ko INNER JOIN oya ON ko.oya_id = oya.id'); __PACKAGE__->has_a( oya => 'Moco::Model::Oya', { key => 'id' } #{ key => 'oya_p' } );
join
DBIx::Classのように、joinしたら双方のテーブルの値を持つ新たなオブジェクトを作るのかと思ったら、ちょっと違った。
双方のテーブルの値を持とうとして、同じ名前のカラムが有ったら、上書きする。
例。
双方のテーブルが同じ名前のカラムを持つ場合
- 主キー:id
- 所持カラム:name
my $koya = Moco::Model::KoOya->search(where => "ko.id = 2")->first; p $koya; p $koya->oya;
$VAR1 = bless( { 'oya_id' => '2', 'created_at' => '2009-07-07 21:39:51', 'updated_at' => '2009-07-07 21:39:51', 'changed_cols' => {}, 'name' => 'oya2', 'id' => '2' }, 'Moco::Model::KoOya' ); $VAR1 = bless( { 'created_at' => '2009-07-07 21:39:51', 'updated_at' => '2009-07-07 21:39:51', 'changed_cols' => {}, 'name' => 'oya2', 'object_id' => 'Moco::Model::Oya-id-2', 'id' => '2' }, 'Moco::Model::Oya' );
双方のテーブルが同じ名前のカラムを持たない場合
- 主キー:${TABLE}_p
- 所持カラム:${TABLE}_name
my $koya = Moco::Model::KoOya->search(where => "ko.ko_p = 2")->first; p $koya; p $koya->oya;
$VAR1 = bless( { 'oya_id' => '2', 'created_at' => '2009-07-07 21:56:41', 'ko_p' => '2', 'ko_name' => 'ko2', 'updated_at' => '2009-07-07 21:56:41', 'oya_name' => 'oya2', 'changed_cols' => {}, 'oya_p' => '2' }, 'Moco::Model::KoOya' ); $VAR1 = bless( { 'created_at' => '2009-07-07 21:56:41', 'oya_name' => 'oya2', 'updated_at' => '2009-07-07 21:56:41', 'changed_cols' => {}, 'object_id' => 'Moco::Model::Oya-oya_p-2', 'oya_p' => '2' }, 'Moco::Model::Oya' );
前者ではidとnameのカラムが上書きされている。相当困る。
どう考えても自分が間違ってると思うんだけど、回避策分からず。
has_many
DBICのように $parent->child->id とか出来るはずなんだけど。
kosというメソッドで、Oyaから複数のKoを得られるようにしてみよう。
package Moco::Model::Oya; use base qw/Moco::Model::Moco/; use Moco::Utils; __PACKAGE__->table('oya'); __PACKAGE__->has_many( kos => 'Moco::Model::Ko', { key => 'id' } #{ key => 'oya_p' } );
my $oya = Moco::Model::Oya->retrieve_all; p $oya; my @kos = $oya->kos; p \@kos;
$VAR1 = bless( [ bless( { 'created_at' => '2009-07-07 22:03:20', 'updated_at' => '2009-07-07 22:03:20', 'changed_cols' => {}, 'name' => 'oya1', 'object_id' => 'Moco::Model::Oya-id-1', 'id' => '1' }, 'Moco::Model::Oya' ), bless( { 'created_at' => '2009-07-07 22:03:20', 'updated_at' => '2009-07-07 22:03:20', 'changed_cols' => {}, 'name' => 'oya2', 'object_id' => 'Moco::Model::Oya-id-2', 'id' => '2' }, 'Moco::Model::Oya' ) ], 'DBIx::MoCo::List' ); $VAR1 = [ '' ];
取れない…
最も力を入れてアピールしたい事
どうか誰か俺の間違いを正してもらえませんか。助けてヘルプ。