FuelPHP

[FuelPHP] ORMで取得したデータとそのカウント数が違う

fuel_logoORMでのデータ取得時にrelated、およびpagenationを指定した場合、カウントした件数と、取得したデータに相違がある場合があります。
例えば、カウント数は10件あるのに、実際に取得したデータは9件分しかない。

実際にクエリを見てみると、カウント時とデータ取得時では全然違っていて、それが原因で結果が違ってくる。

色々調べていると、fuelphpのマニュアルにこう書いてありました。

ORM は常にクエリの結果に一貫性があることを確認します。関連するモデルが含まれているクエリを実行すると、 すべての関連する結果がフェッチされたかどうかを確認するためにサブクエリが生成されます。 これは、limit で定義した以上のレコードがフェッチされることを意味しています。 一旦不完全な結果セットを操作し始めると、関連するモデルにとてもわるい影響が起こるためです。

もしあなたがその結果を絶対に操作しないことが確信できる場合(たとえば pagination のみに利用する場合) 代わりに rows_limit()rows_offset() を利用する事で クエリに対して limit, offset を強制することができます。

そこで、limitとoffsetの部分をrows_limitとrows_offsetに置き換えることで正常な結果を得ることができます。

$query->rows_limit($pagination->per_page);
$query->rows_offset($pagination->offset);

Posted in FuelPHP| [FuelPHP] ORMで取得したデータとそのカウント数が違う はコメントを受け付けていません。

[FuelPHP] リレーション先のテーブルも含めて連続してvalidateする

modelにリレーションの設定をしていると、バリデーション時にリレーション元とリレーション先の複数テーブルにバリデーションしなければならないケースがあります。

$val = Model_User::validate('edit');
if ($val->run())
{
    $val2 = Model_Category::validate('edit');
    if ($val2->run())
    {
    }
}

しかし、上記のようにしてしまうと、

Form instance already exists, cannot be recreated. Use instance() instead of forge() to retrieve the existing instance.

と、このようなエラーが出ます。 これはmodel内での Validation::forge(xxxx) のxxxxが同じであるため、すでにインスタンスが存在することによるエラーです。

このエラーが出た場合、単純に

$val = Model_User::validate('edit');
if ($val->run())
{
    $val2 = Model_Category::validate('edit2');
    if ($val2->run())
    {
    }
}

と、

validate内の引数を変えてあげるだけで問題なく実行できます。

p.s.
一年半もブログを更新してなかった…

Posted in FuelPHP| Tagged | [FuelPHP] リレーション先のテーブルも含めて連続してvalidateする はコメントを受け付けていません。