LoginSignup
1
2

More than 5 years have passed since last update.

ID列名がidではないテーブルをgasormで使えるようにしてみる

Last updated at Posted at 2016-09-14

gasormはcodeigniter用のORMですが、
今回少し使ってみたので、単純に既存のテーブル構造から、シンプルにデータを抜いてくるところまでを作ってみました。

既存のテーブルを題材にしたので、idとか user_idのように綺麗にORMに適用できなかったので、少し手こずりました。

  • お客様モデル
customer.php
<?php namespace Model;
use \Gas\Core;
use \Gas\ORM;

if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Customer extends ORM{

    public function _init()
    {
        /**
         * プライマリキー 単に "id"の場合は省略できます。
         */
        $this->primary_key = "CUSTOMER_NO";
        /**
         * リレーション
         * ねぎテーブル側にCUSTOMER_NOがあり、belongs_toでCustomerに属するようにする。
         * ねぎは一つしか持てません。
         */
        self::$relationships = array (
            'green_onion' => ORM::has_one('\\Model\\Green_onion')
        );

        /**
         * フィルード定義とバリデーションルール
         */
        self::$fields = array(
            'CUSTOMER_NO' => ORM::field('int[8]'),
            'NAME' =>  ORM::field('char[128]'),
            "CREATE_AT" => ORM::field("datetime"),
            "UPDATE_AT" => ORM::field("datetime"),
        );

    }
}
  • ねぎモデル
green_onion.php
<?php namespace Model;
use \Gas\Core;
use \Gas\ORM;

if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Green_onion extends ORM{


    /**
     * プライマリキー 単に "id"の場合は省略できます。
     */
    public $primary_key="GREEN_ONION_NO";
    /**
     * 外部キー 参照先テーブル名_id の場合は省略できます
     * このモデルのテーブルに持っている、お客様を示す外部キーを指定する。
     */
    public $foreign_key = array('\\Model\\Customer' => 'CUSTOMER_NO');

    public function _init()
    {

       /**
         * リレーション
         */
        self::$relationships = array (
            'customer'          =>     ORM::belongs_to('\\Model\\Customer')
        );

        /**
         * フィルード定義とバリデーションルール
         * 定義しておかないと値が取れません。
         */
        self::$fields= array(
            "GREEN_ONION_NO" => ORM::field("int[8]"),
            "CUSTOMER_NO" => ORM::field("char[8]"),
            "CREATE_AT" => ORM::field("datetime"),
            "UPDATE_AT" => ORM::field("datetime"),
        );

    }
}
  • ねぎコントローラ
green_onions.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Green_onions extends CI_Controller
{

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

    public function show_list() {

        $green_onion = new Model\Green_onion();
        $onions = $green_onion->all();
        $data["onions"]=$onions;

        $this->load->view("green_onions_list",$data);
    }

}
  • ねぎ一覧ビュー
green_onions_list.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');?>
<h1>ねぎ一覧</h1>

<table class="data_tables">
    <thead>
        <tr>
            <th>ねぎ番号</th>
            <th>ねぎを持っているお客様</th>
        </tr>
    </thead>

    <tbody>
        <?php foreach ($onions as $onion) { ?>
        <tr>
            <td><?php echo $onion->GREEN_ONION_NO ?></td>
            <td><?php echo $onion->green_onion()->NAME ?></td>
        <?php } ?>
    </tbody>
</table>

使い方的にはこれでいけるはずなのですが...

しかしこれだと取ってこれませんでした。
あまり日本語の情報がないので、結局gasormのコードを読んだのですが。
orm.phpのコンストラクタで、プライマリキーが設定されていると外部キーを設定しない条件があり、そこを修正せざるをえませんでした。

正しい修正の方法なのか、いまいちよくわかりません。
間違っていたら教えてください。

third_party/gas/classes/orm.php


        // We really deal with composite keys here
        //@remark プライマリキーの条件を削除、設定されていようがいまいが、外部キーを処理する
        /*
        if (empty($this->primary_key))
        {
        */
            if ( ! empty($this->foreign_key))
            {
                // Validate foreign keys for consistency naming convention recognizer
                $foreign_key = array();

                foreach($this->foreign_key as $namespace => $fk)
                {
                    $foreign_key[strtolower($namespace)] = $fk;
                }

                $this->foreign_key = $foreign_key;
            }
            else
            {
                // If so far we didnt have any keys yet, 
                // then hopefully someone is really follow Gas convention
                // while he define his entity relationship (yes, YOU!)
                foreach ($this->meta->get('entities') as $name => $entity)
                {
                    if ($entity['type'] == 'belongs_to')
                    {
                        $child_name     = $entity['child'];
                        $child_instance = new $child_name;
                        $child_table    = $child_instance->table;
                        $child_key      = $child_instance->primary_key;

                        $this->foreign_key[strtolower($child_name)] = $child_table.'_'.$child_key;
                    }
                }
            }
        //}


gasormは気になるコメントがコード内のそこここに書かれています。
大丈夫なのでしょうか。

補足で、二つほど単純なhackを書いておきます。

  • テーブル名を大文字にしたい場合のhack
third_party/gas/classes/orm.php
    final public function validate_table()
    {
        // If there is no table name set, use model name based by namespace path
        if (empty($this->table))
        {
            // Parse namespace into table spec
            if (array_key_exists($this->namespace, Core::$path['model']))
            {
                // Namespace already in the correct position
                $namespace = strtolower($this->namespace);
            }
            else
            {
                // Get the namespace from parent
                foreach (Core::$path['model'] as $parent => $path)
                {
                    if (strpos($this->namespace, $parent) !== FALSE)
                    {
                        $namespace = strtolower($parent);
                        break;
                    }
                }
            }

            // Define table, path and set the table properties
            $table       = str_replace($namespace.'\\', '', $this->model());
            //@remark テーブル名を大文字に変更
            /*
            $path        = strtolower(str_replace('\\', '_', $table));
            $this->table = strtolower($path);
            */
            $path        = strtoupper(str_replace('\\', '_', $table));
            $this->table = strtoupper($path);
        }

        return $this;
    }

  • IDの値に数値ではなく文字列を使いたい場合のhack
third_party/gas/classes/core.php

    public static function generate_clause($domain, $key, $identifier, $ids = '')
    {
       //...(中略)                 

        // Do we need to replace the string identifier
        // Either into sub-query or the real COLUMN value(s) ?
           // @remark ↑うん、やってよ! と思いました。
        if ( ! empty($ids))
        {
            //@remark idsが通常だとクオート処理されないので、文字列ならクオート処理する。
            if (is_string($ids)) {
               $ids="'".$ids."'";
            }
            $pattern = sprintf($pattern, $ids);
        }

        // Statement is ready
        return $pattern;
    }
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2