プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
FuelPHP1.6、ORMモデルのプロパティにはプライマリキーも含めないと駄目らしい。
FuelPHP1.6、ORMモデルでfind()時の取得カラムを理解する。」で書いた通り、
find()の取得カラムは

[\Orm\Modelを継承したモデル名]::properties();

の取得結果と

[\Orm\Modelを継承したモデル名]::primary_key();

の取得結果を合体したものでした。

そのため

pk_id:プライマリキー(数値:自動採番)
column_varchar01:文字列
column_int02:数値
column_varchar02:文字列

なテーブルのORMモデルを

<?php
class Model_Test02 extends \Orm\Model
{
    //使用するtable
    protected static $_table_name = "tbl_test01";

    //プライマリキー
    protected static $_primary_key = array('pk_id');

    //フィールド名
    protected static $_properties = array(
        'column_varchar01',
        'column_int02',
        'column_varchar02'
    );
}

のように作っていたのですよ。
プライマリキー項目「pk_id」を「$_properties」に書いていなかったのです。

find()をしている分にはこれで問題無かったのですが、save()実行時にエラーが発生。

public function action_add()
{
    //インスタンス生成
    $mt = Model_Test02::forge();

    //値設定
    $data = array(
        'column_varchar01' => 'かかか',
        'column_int02' => 11,
        'column_varchar02' => 'ききき',
    );
    $mt->set($data);

    //保存
    if(!$mt->save()){
        print "保存失敗";
    }else{
        print "保存成功";
    }
}

なコードを実行したところ

Error!
OutOfBoundsException [ Error ]: Property "pk_id" not found for Model_Test02.

PKGPATH/orm/classes/model.php @ line 1038

1033 {
1034 return $this->_custom_data[$property];
1035 }
1036 else
1037 {
1038 throw new \OutOfBoundsException('Property "'.$property.'" not found for '.get_class($this).'.');
1039 }
1040 }
1041
1042 /**
1043 * Set

なエラーが出やがりました。

あれ?でもデータはinsertされてるなぁ。

原因をあれやこれやと追って行ったところ、問題の場所は

fuel\packages\orm\classes\model.php

の中のcreate()メソッドの中にありました。

/**
 * Save using INSERT
 */
protected function create()
{
(中略)

    // Set all current values
    $query = Query::forge(get_called_class(), static::connection(true));
    $primary_key = static::primary_key();
    $properties  = array_keys(static::properties());
    foreach ($properties as $p)
    {
        if ( ! (in_array($p, $primary_key) and is_null($this->{$p})))
        {
            $query->set($p, $this->{$p});
        }
    }

    // Insert!
    $id = $query->insert();
    // when there's one PK it might be auto-incremented, get it and set it
    if (count($primary_key) == 1 and $id !== false)
    {

        $pk = reset($primary_key);
        // only set it if it hasn't been set manually
        is_null($this->{$pk}) and $this->{$pk} = $id;
    }

    // update the original properties on creation and cache object for future retrieval in this request
    $this->_is_new = false;
    $this->_original = $this->_data;
    static::$_cached_objects[get_class($this)][static::implode_pk($this)] = $this;

    $this->observe('after_insert');

    return $id !== false;
}



if (count($primary_key) == 1 and $id !== false)
{

    $pk = reset($primary_key);
    // only set it if it hasn't been set manually
    is_null($this->{$pk}) and $this->{$pk} = $id;
}

// update the original properties on creation and cache object for future retrieval in this request
$this->_is_new = false;
$this->_original = $this->_data;
static::$_cached_objects[get_class($this)][static::implode_pk($this)] = $this;

の部分が原因でしたよ。

どうやらinsert時に払い出されたプライマリキーの値を
プロパティに設定してくれているようなのです。
そしてプロパティに該当項目(今回はpk_id)が無かったのでエラーになちゃったみたい。

てことは結局テーブルの項目をそのままプロパティにしないと駄目なのですね。

なーんだ。

じゃあfind()の中の取得項目にプライマリキーを補完してくれる処理は
活用しようがないのか(´・ω・`)
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:FuelPHP  thema:パソコンな日々 - genre:コンピュータ  Posted by ササキマコト 

  関連記事