1

私は何をしようとしていますか?
3つのフィールド(1つは非表示、ID)があり、ユーザーは検証に合格するために他の2つのうちの1つに入力する必要があります。
したがって、両方のフィールドが空の場合、ユーザーは検証に失敗する必要がありますが、一方が完了すると合格します。

1 2 3
A 0 B True
AB 0 True
A 0 0 False

私はCakePHPv2.1.3を使用しているので、新しい検証ルールの拡張機能にアクセスできます。

問題
私は両方のフィールドを同時にチェックする信頼できる方法を見つけることができないようです。私はこれまで$this->dataからmodelてみましたが、検証では一度に1つのデータインスタンスしか渡さないことがわかりました。したがって、フィールドを比較する方法はないようです。

私が今まで持っているもの

/**
 * Custom validation to see if either of the two fields are set, if neither are, then we fail, if at least one is, we pass
 * @param array $check
 * @return boolean 
 */
public function checkAttributes($check){
    var_dump($check);
    var_dump($this->data);
    echo "<hr>";

    // Check for an id value picked from a list
    if(@is_numeric($check['attribute_value_id']) && isset($this->data['AdvertAttributeValue']['attribute_value_id'])){
        return true;
    }

    // Check for a date value selected
    if(@is_array($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){
        return true;
    }

    // Check for a text value
    if(@is_string($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){
        return true;
    }

    return false;
}

$this->dataインスタンスに関連するすべてのフィールドが含まれていないため、チェックできないと思うので、これはうまくいかないようです。

また
、大きな数値配列を渡していることにも言及する必要があります。したがって、これらのフィールドはページに複数回表示され、現在は12次元です。したがって$this->data、ディメンションとは名前が付けられていないため、直接アクセスするのは困難です。$this->data['Model'][<num>]['field'] = value


検証

public $validate = array(
    'attribute_value_id'=>array(
        'notempty'=>array(
            'rule'=>'checkAttributes',
            'message'=>'Please select a value for your attribute',
            'required'=>true,
        ),
    ),
    'attribute_value_text'=>array(
        'notempty'=>array(
            'rule'=>'checkAttributes',
            'message'=>'You must enter text for this attribute',
            'required'=>true,
        ),
    )
);

データダンプ
ここでは、上記の出力を示しますvar_dump()。モデルには2つの検証ルールがattribute_value_idあります。1つは用、もう1つは用です。attribute_value_text

// An id field selected from a list
array // $check
  'attribute_value_id' => string '1' (length=1)
array // $this->data
  'AdvertAttributeValue' => 
    array
      'attribute_value_id' => string '1' (length=1)
      'id' => string '' (length=0)

// A text field
// Validating first time around on the id field
array // $check
  'attribute_value_id' => string '' (length=0)
array // $this->data
  'AdvertAttributeValue' => 
    array
      'attribute_value_id' => string '' (length=0)
      'id' => string '' (length=0)
      'attribute_value_text' => string '50' (length=2)
// Validating second time around on the text field
array // $check
  'attribute_value_text' => string '50' (length=2)
array // $this->data
  'AdvertAttributeValue' => 
    array
      'attribute_value_id' => string '' (length=0)
      'id' => string '' (length=0)
      'attribute_value_text' => string '50' (length=2)  
// A date field
array // $check
  'attribute_value_id' => string '' (length=0)
array // $this->data
  'AdvertAttributeValue' => 
    array
      'attribute_value_id' => string '' (length=0)
      'id' => string '' (length=0)
      'attribute_value_text' => 
        array
          'month' => string '06' (length=2)
          'day' => string '28' (length=2)
          'year' => string '2012' (length=4)
4

2 に答える 2

0

Model ::$dataまたはModel::beforeValidate()を利用できます。

于 2012-06-27T21:43:15.270 に答える
0

saveAll()メソッドは、または必要に応じて呼び出すだけsaveMany()ですsaveAssociated()。これらのメソッドは、デフォルトで、データを保存する前に(への呼び出しを介してvalidateMany())すべてのデータを検証しようとします。ただし、ソースでわかるように、その関数は各アイテムを個別に検証するため、検証コードは他のレコードにアクセスできません。

私が理解しているように、保存する前に、複数のレコード間で相互検証する必要があります。私はそれを行ったことがありませんが、コントローラーでの検証の場合のように聞こえます。レコードの内部整合性を確保するために、Model::validate()またはを呼び出すことができます。Model::validateAll()次に、コントローラーは、クロスレコード検証に必要なロジックを実装することもできます。それが完了したら、検証を無効にして保存呼び出しを行うことができます。

$this->myModel->saveAll($this->request->data, array('validate'=>false));

これを行う前に、データをモデルに設定する必要があることに注意してください。

$this->myModel->set($this->request->data);

これにより、理想的にはモデルに含まれるはずのコントローラーに多くの余分なコードが追加されることに気付きました。モデルコールバックの1つを介して実行できる可能性があると思いますが、その方法はわかりません。

于 2012-07-11T17:32:26.290 に答える