0

Kohana ORM の検証は、次を使用して行われます。rules

function rules()
{
  return array(
    'username' => array(
      array('not_empty'),
      array(array($this, 'availability')),
    )
  );
}

を使用して JSON エンコードされた列を検証するのに苦労しています$_serialize_columns

class Model_Admin extends ORM {
  protected $_belongs_to = array();
  protected $_has_many = array(
    'plans' => array(),
    'groups' => array(),
    'transactions' => array(),
    'logins' => array()
  );

  protected $_serialize_columns = array('data');

  /**
   * @param array $data
   * @param Validation $validation
   *
   * @return bool
   */
  public function data($data, $validation)
  {
     return 
       Validation::factory(json_decode($data, TRUE))
       // ... rules ...
       ->check();
  }

  public function rules()
  {
     return array(
       'data' => array(
         array(array($this, 'data'), array(':value',':validation')
       )
     );
  }
}

エンコードされる配列は次のとおりです。

array(
  'name' => '',
  'address' => '',
  'phone' => '',
  'postalcode' => ''
);

ORM は検証を行う前にフィルターを実行するため、dataメソッドは json でエンコードされたデータを受け取ります。そのため、それを連想配列に変換してから、新しい検証オブジェクトを作成して、その配列の内容を具体的に確認する必要があります。Validation別のValidationインスタンスのルールをマージできないため

4

1 に答える 1

0

更新された回答

save()内部モデル検証オブジェクトがチェックされるため、2 番目の検証オブジェクトを使用する必要があります。これは、検証ルールからチェックされる検証オブジェクトに追加されたルールが無視されることを意味します (Validation->check()ループする前にローカル スコープにルールをインポートします)。

データ自体は技術的には別のオブジェクトであるため (オブジェクトの関係という意味では、検証が必要な独自のデータセットがあります)、理想的な解決策は、データを保存する実際のモデルを作成する方法を見つけることです。

適切なデータベース列定義を使用してデータを保存することには、他にも多くの利点があります。特に、データ プロパティのルックアップを実行したり、その場で変更を行う必要がある場合などです (それ以外の場合は、すべての行で潜在的にデータ列をシリアル化解除する必要があります)。

いくつかの代替手段がありますが、それらは私にはお粗末のように感じます:

  1. データ オブジェクトを表すモデルを作成し、ルールを追加してcheck()、データの検証に使用します (問題: 多くのメンテナンスが必要になります。実際のテーブルがないということは、列を手動で定義する必要があることを意味します)。

  2. 管理モデルでデータを実際の列として設定し、設定時にデータ列に変換するフィルターを使用します (問題: 列を手動で定義し、追加の列を保存操作から除外する必要があります)。

これが何かの役に立てば幸いです。

元の回答

Kohana ORMsave()メソッドでは、メインの ORM 検証オブジェクトの名前空間にマージされる「追加の」検証オブジェクトを含めることができます。

これはここに簡単に文書化されています。

私が正しく理解していれば、あなたは次のようなことをしようとしていると思います:

// another script, e.g., a controller

// Create the model
$admin = ORM::factory('Admin');

// $data = the data as an array, before serialization ...

$extra_validation = Validation::factory($data)
                    // add ->rule() calls here, but DO NOT chain ->check()
                    ;

// Set $data in the model if it is going to be saved, e.g., $admin->data = $data;
// Set other data... e.g., $admin->foo = 'bar';

// Save the model
try {
    $admin->save($extra_validation);
}
catch (ORM_Validation_Exception $e)
{
    // Manipulate the exception result
}

この例では、別の検証オブジェクトを作成する必要がありますが、1 つのブロックですべての例外をキャッチできるようになりました。人間が読めるエラー メッセージを提供するために i18n メッセージを使用している場合は、var_dump()または同様の onを使用して名前空間を確認することをお勧めします。$e->errors()応答で「_external」という名前の名前空間が作成されていることがわかります。

于 2012-12-19T16:36:40.650 に答える