モデルの拡張

シェアする

CodeigniterのモデルはDBのテーブル名がモデルクラス名が直結していません。

この為、モデルクラスからDBへアクセスする際、常にアクセス先テーブルを以下のように指定する必要があります。

$this->db->get('テーブル名');

些細な事ですが、このテーブル指定の手間と、モデルクラス名とテーブル名の紐付けを直結させることで、モデルクラスから直接テーブルへアクセスできる拡張機能(コアライブラリのMY_Model.php)をご紹介します。

仕様方法

コアライブラリの設置

MY_Model.zip

上記リンクより、MY_Model.zipをダウンロード、解凍して、以下のディレクトリに配置してください。

application/core/

モデルクラスの作成

以下のようにモデルクラスを作成します。

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class User_model extends MY_Model {

 // DBテーブル名が「user」の場合、以下のように指定
 public $table_name = 'user';

 public function __construct()
 {
  parent::__construct();
 }

}

これで利用準備は整いました。

Users_modelクラスは、コアライブラリのMY_Modelを継承し且つ、table_nameにはDBテーブル名が指定されている点がポイントになります。

機能紹介

以下に、User_modelを例に拡張機能を紹介します。

$this->User_model->new_object();

これは、userテーブルの空のインスタンスを生成します。

入力フォームでCRUD(create, read, update, delete )を生成する際、登録(create)と更新(update) のテンプレートを一つに纏める為の機能を提供します。

この機能により以下のように入力フォームタグの初期値の設定できます。

<?php echo form_input('email', set_value('email', $user->email)) ?>

$this->User_model->fields();

これは、Codeigniterの、field_data と同じ結果を返します。

$this->User_model->find_one(カラム名, 値);

単一のデータを取得します。

複数の条件を指定する場合は、第一引数に配列にて指定できます。

$this->User_model->find(条件指定, 取得数, オフセット);

複数の条件を第一引数へ配列で指定し、複数のデータを取得できます。

また、ページ処理する場合は、第二引数に取得するページ数、第三引数に取得開始位置を指定します。

$this->User_model->find_all();

データを全件取得します。

$this->User_model->find_update(キー”id”)

 フォームからのデータをDBに登録・更新する際のインスタンスを生成、制御します。
  • 登録時:
    空のインスタンスを返します。
  • 更新時:
    更新対象のデータがセットされたインスタンスを返します。

これによりコントローラ内で以下の様に使用する事ができます。

<?php
 
 // 省略

 public function update()
 {
 $user = $this->User_model->find_update($this->input->post('id'));

 $user->id = $this->input->post('id');
 $user->name = $this->input->post('name');
 $user->email = $this->input->post('email');

$this->User_model->total_rows();

データの全件数を返します。

$this->User_model->save(データ);

データ(インスタンス)にキー(id)が、指定されていない場合は新規でインスタンスを保存します。

キー(id)が指定されている場合は、対象のデータを更新します。

<?php
 
 // 省略

 public function update()
 {
 // 省略

 $user->name = $this->input->post('name');
 $user->email = $this->input->post('email');
 
 $this->User_model->save($user); 
 }

日付管理補助機能のご紹介

当、拡張機能には、データの、登録及び更新日付けを自動で更新制御する機能が組み込まれています。

この機能は以下の箇所を編集する事で対象のカラムを独自で指定する事ができます。

<?php
 
 // 省略
 
 // 作成日時のカラム名指定
 private $updated_name = 'updated_at';

 // 更新日時のカラム名指定
 private $created_name = 'created_at';

利用制限

このライブリはデータベースにスキーマー構成に以下のルールがあります。

  • 全てのテーブルにプライマリキーとなる カラム(id)が指定されている事

MY_Model 拡張コアライブラリ(ソースコード)

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Model extends CI_Model
{
  /**
   * $updated_name
   *
   * DBテーブルカラムで共通名として使用している更新年月日名を指定
   */
  private $updated_name = 'updated_at';
  /**
   * $created_name
   *
   * DBテーブルカラムで共通名として使用している登録年月日名を指定
   */
  private $created_name = 'created_at';
  public function __construct()
  {
    parent::__construct();
  }
  /**
   * new_object
   *
   * 空のインスタンスを作成
   */
  public function new_object()
  {
    $obj = new static;
    unset($obj->table_name);
    foreach($this->db->list_fields($this->table_name) as $name)
    {
      $obj->$name = FALSE;
    }
    return $obj;
  }
  /**
   * fields
   *
   * カラム情報を取得
   */
  public function fields()
  {
    return $this->db->field_data($this->table_name);
  }
  /**
   * find_one
   *
   * 指定のカラムに対し、単一のデータを返す
   * 結果が無い場合や複数ある場合は、FALSEを返す
   */
  public function find_one($name, $value = FALSE)
  {
    if(is_array($name) && $value === FALSE)
    {
      foreach($name as $k => $v)
      {
        $this->db->where($k, $v);
      }
 
    }else
    {
      $this->db->where($name, $value);
    }
 
    $res = $this->db->get($this->table_name);
    if($res->num_rows() == 1){
      return $res->row();
    }
    return FALSE;
  }
  /**
   * find
   *
   * 検索(Pagination引数付)
   */
  public function find($option = array(), $limit = FALSE, $offset)
  {
    if(is_array($options) && count($options) > 0)
    {
      foreach($options as $key => $value)
      {
        $this->db->where($key, $value);
      }
    }
    if($limit !== FALSE)
    {
      return $this->db->get($this->table_name, $limit, $offset);
    }
    return $this->db->get($this->table_name);
  }
  /**
   * find_all
   *
   * 全データを取得
   */
  public function find_all()
  {
    return $this->db->get($this->table_name);
  }
  /**
   * find_update
   *
   * フォームからPOSTされた更新・登録対象のインスタンスを返す
   */
  public function find_update($id = FALSE)
  {
    if($id !== FALSE){
      $res = $this->find_one('id', $id);
      if($res !== FALSE) return $res;
    }
 
    return $this->new_object();
  }
  /**
   * total_rows
   *
   * 登録データ数を取得
   */
  public function total_rows()
  {
    return $this->db->get($this->table_name)->num_rows();
  }
  /**
   * save
   *
   * $attr にキーが無い場合は追加[insert]、キーがある場合は更新[update]を行う
   * 処理後、対象のデータをオブジェクトで返す
   */
  public function save($args)
  {
    $attr = array();
    $current_timestamp = date('Y-m-d H:i:s');
 
    foreach($this->fields() as $field)
    {
      $column_name = $field->name;
      if(!empty($args->$column_name)) $attr[$column_name] = $args->$column_name;
      if($column_name == $this->updated_name || ($args->id == '' && $column_name == $this->created_name)){
        $attr[$name] = $current_timestamp;
      }
    }
    $res = FALSE;
    if($args->id != ''){
      $this->db->where('id', $args->id);
      $this->db->update($this->table_name, $attr);
    }else {
      $this->db->insert($this->table_name, $attr);
      $args->id = $this->find_one($this->db->insert_id());
    }
    return $this->find_one('id', $args->id);
  }
  /**
   * remove
   *
   * 削除
   */
  public function remove($args)
  {
    foreach($this->fields() as $field)
    {
      $column_name = $field->name;
      $this->db->where($column_name, $args->$column_name);
    }
 
    return $this->db->delete($this->table_name);
  }
}