FuelPHPは、標準ではユニークチェック用のバリデーションルールが用意されていないので、ユニークチェックをしたい場合は独自のバリデーションを拡張する必要があります。
公式ドキュメントの Validation クラスを拡張する に独自バリデーションの追加方法が記載されていますが、この例がちょうどユニークチェックの追加方法になっています。
以下のコードは、ドキュメントの例に、idの比較を含めて編集時にも対応していました。
// fuel/app/classes/myvalidation.php
<?php
class MyValidation
{
// 静的メソッドであることに注意する
public static function _validation_unique($val, $options)
{
list($table, $field) = explode('.', $options);
$id = Validation::active()->input('id');
$result = DB::select("LOWER (\"$field\")")
->where($field, '=', Str::lower($val))
->where('id', '!=', $id) // 編集時には、同じレコードを外してチェック
->from($table)->execute();
Validation::active()->set_message('unique', '「:label 」はユニークです。「:value」は既に登録されています。');
return ! ($result->count() > 0);
}
}
モデルへの適用
// fuel/app/classes/model/user.php
<?php
class Model_User extends \Orm\Model
{
...
public static function validate($factory)
{
$val = Validation::forge($factory);
$val->add_callable('MyValidation');
$val->add_field('screen_name', 'screen_name', 'required|max_length[255]')
->add_rule('unique', 'users.code');
return $val;
}
...
}
また、idは、postパラメータに含める必要があるため編集フォームに含めます。
// fuel/app/views/user/_form.php
<?php echo Form::hidden('id', Input::post('id', isset($user) ? $user->id : '')); ?>
ここは、ちょっと気持ちが悪い。しかし、他にいい方法が思いつかない。