CodeIgniterのモデルを使いやすくしよう

CodeIgniterのモデルは、自由度が高いですね。他のフレームワークでは、テーブルとモデルが密な関係になっていいて、ちょっと扱いづらいところがあるんですが、CodeIgniterは自由すぎるぐらい自由です。CodeIgniterのソースコードを読むと、その途方も無い自由さは分かります。ただ、自由すぎるがゆえに不便なところもあります。これを使いやすくしましょうというのが、ここでテーマです。

不便その1:いちいちテーブル名を指定すること

たとえば、users_modelというモデルがあるとしましょう。そこから usersテーブルのレコードを引っ張ってくる時は、

$query = $this->db->get_where('users', array('id' => $id));
$result = $query->result_array();

こんな感じで取得します。自由だけど少し面倒ですね。わざわざテーブル名を指定しています。自由度が高いゆえなんですけどね。ぼくとしては、usersモデルの中からusersテーブルのレコードを取得する時は、こう書きたいです。

$result = $this->get(array('id' -> $id));

不便その2:よくjoinするので、結局SQLを直に書いてしまう

さて、他のテーブルとjoin(結合)する時のことを考えてみましょう。たとえば、payments(支払情報)テーブルのレコードを取得する時に、users(会員情報)テーブルから常に会員名を結合して取得したい・・・ということはよくありますね。そんな時、ふつうはこんな感じで書くと思います。


$this->db->select('payments.*,users.name');
$this->db->from('payments');
$this->db->join('users', 'payments.user_id = users.id');
$this->db->where('payments.user_id', $id);
$query = $this->db->get();
$result = $quert->result_array();

面倒ですよね。こんなことならSQLを直に書いちゃいますよ。
でも、フレームワークを使うからにはSQLはあんまり書きたくないんですよね。(といいつつガリゴリ書いていますが)
こんなときでも、よくばりな私は

$result = $this->get(array('payments.user_id' -> $id));
(paymentsモデルから呼び出すことを想定しています)

1行で済ませたいのです。これで$resultに会員名も含まれていたら素敵。
(どっかでアソシエーション設定はしておくのですが、毎回結合条件を書かなくて済みます)

不便その3:getメソッドぐらい用意して欲しい

たとえば、コントローラから特定ユーザーの情報を取得したいって状況があるとします。usersモデルにgetメソッドなるものを書いて中継させると思います。だけど、テーブルから単純にレコードを取得するなんてよくある処理じゃないですか。すべてのモデルにgetメソッドをいそいそと実装するのもバカバカしい気がします。せめてget/insert/update/deleteメソッドがモデルにあったらなぁ。

解決策

私はこれらの問題を解決するために、コアのモデルを拡張することで、これらを実現しています。かれこれ3年以上愛用しています。コアモデルを拡張するには、core/ の中に MY_Model.php という名前でファイルを作成します。
私の拡張モデルは以下の様になっています。

そして、原則テーブルごとにモデルを作成しています。(モデルを作らないテーブルもあります)
usersテーブルにはusersモデルを作成します。ここではusersモデルを例にしましょう。

models/ディレクトリに 以下の内容で、Users_model.phpというファイルを作成します。

このようなファイルをテーブルごとに作るんです。usersという箇所を該当テーブル名に差し替えればいいだけ。
これで準備完了です。

非常にDBへのアクセスが楽になります。
たとえばusersモデルからusersテーブルにアクセスする時は

$result = $this->get(array('users.id' -> $id));

これだけ。
コントローラからusersテーブルにアクセスするときは、


$this->load->model('users_model');
$users = $this->users_model->get();

簡単ですよね。

このモデル拡張は他にも機能をもたせています。簡単にjoinさせることもできますし、すこし複雑なクエリもSQLを書かずして構築できます。それは次回以降にご紹介しましょう。

この続きは現在作成中です。