Rowクラスの拡張について #13B!

こんにちわ!nekokakです!

十三日目はDBIx::SkinnyのRowクラスの拡張についてです。

Rowクラスとは、DB検索結果のレコードをオブジェクト化するクラスになります。

DBIx::Skinnyでは基本的にユーザがRowクラスを定義する必要がありません。

Rowクラスは自動で生成されるからです。

たとえば、

my $row = $db->singe('user', {name => 'nekokak'});

このような処理を行った場合、Rowクラスが自動で生成されますが、

Rowクラスのパッケージ名は、

DBIx::Skinny::Row::Cdb3ee45d06b8098ef489e14b9bbb801741e549c8

という名前になっています。

これは発行するSQLに応じたRowクラスを生成するため、

発行するSQLをsha1hashした値をベースにクラスを作り利用しています。

基本RowクラスにはSELECTしたカラム名をアクセサにしたメソッドのみが設定されていますので

$row->name; # nekokak

といった形でデータにアクセスすることが可能です。

基本的には取得したカラムにアクセスできれば十分だとはおもいますが、

Rowクラスを拡張したくなることもあるでしょう。

例えば、userテーブルにはfirst_name / last_nameというカラムが別々で存在している場合に、

いちいち

prit $row->first_name . ' ' . $row->last_name;

というようなことをあちこち書いて回るのは面倒ですよね?

そのような場合に、

print $row->full_name;

と、アクセスできれば良いようにしたいとします。

このような場合に、Rowクラスを拡張します。

今回の場合、userテーブルに対して検索をおこなっているので、

Proj::DB::Row::UserというRowクラスをつくりましょう。

package Proj::DB::Row::User;
use strict;
use warnings;
use base 'DBIx::Skinny::Row';
sub full_name {
    my $self = shift;
    return $self->first_name . ' ' . $self->last_name;
}
1;

このようにuserテーブルに対応するRowクラスを作成し、

必要なメソッドを定義するだけです。

簡単ですね!

おっと、はじめに、RowクラスはSQLをsha1hashした値をつかって自動で作ったクラスをつかうって言ったじゃないかといわれそうですが、

DBIx::Skinnyでは対応するRowクラスが存在する場合は、そのRowクラスを使います。

対応するRowクラスがない場合や、search_by_sqlメソッドなどをつかって、このクエリはどのRowクラスに対応させればよいか分からない場合に、

自動で生成したRowクラスをつかうようになります。

なれるまではこの独自Rowクラスと自動Rowクラスの使い分けが難しいこともあるかもしれませんが、

なれれば、必要に応じてRowクラスを拡張できるようになるでしょう。

明日はDBIx::Skinnyで取得したデータのキャッシュ方法などについてです。

have a nice skinny days!:)