2つのフィールドのためのCakePHP isUnique?
-
20-09-2019 - |
質問
私は、ユーザーが2つの電子メールアドレス(email1&EMAIL2)を埋めることが可能な登録フォームを持っています。マーケティングの要件は、(私たちは10人のユーザーを持っていた場合のようにユニークな、そして10 * 2 = 20一意の電子メールアドレスが存在することになる)一意である必要があるということです。
システムがすでにCakePHPの上に構築されているので、私は知っているしたいのですが、箱の外にこの権利を行うことができます(1つのフィールド内で一意)isUnique機能に似たものはありますか?それとも私はこれを自分でコーディングする運命のですか?事前に感謝します。
編集:リチャードの例上に構築され、これは私のために働います:
function checkUnique($data, $fields) {
if (!is_array($fields)) {
$fields = array($fields);
}
foreach($data as $key) {
$checks = $key;
}
if (empty($checks)) {
return true; //allow null
}
foreach($fields as $key) {
$tmp[$key] = $checks;
}
if (isset($this->data[$this->name][$this->primaryKey])) {
$tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this->primaryKey];
}
return $this->isUnique($tmp);
}
解決
私は、CakePHPのGoogleグループでこの解決策を掲載しました
あなたのAppModelに以下を追加します:
/**
* checks is the field value is unqiue in the table
* note: we are overriding the default cakephp isUnique test as the
original appears to be broken
*
* @param string $data Unused ($this->data is used instead)
* @param mnixed $fields field name (or array of field names) to
validate
* @return boolean true if combination of fields is unique
*/
function checkUnique($data, $fields) {
if (!is_array($fields)) {
$fields = array($fields);
}
foreach($fields as $key) {
$tmp[$key] = $this->data[$this->name][$key];
}
if (isset($this->data[$this->name][$this->primaryKey])) {
$tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this-
>primaryKey];
}
return $this->isUnique($tmp, false);
}
}
とモデルの検証に使用されます:
var $validate = array(
"name"=>array(
"unique"=>array(
"rule"=>array("checkUnique", array("name", "institution_id")),
"message"=>"A contact with that name already exists for that
institution"
)
)
);
他のヒント
checkUnique
はちょうどisUnique
のラッパーのように書くことができます。
class AppModel extends Model {
public function checkUnique($ignoredData, $fields, $or = true) {
return $this->isUnique($fields, $or);
}
}
とモデルの検証に使用されます:
public $validate = array(
'name' => array(
'unique' => array(
'rule' => array('checkUnique', array('name', 'institution_id'), false),
'message' => 'A contact with that name already exists for that
institution'
)
)
);
あなたはフィールドのセットは、複数のフィールドを提供することにより、ユニークであり、falseに$かを設定することを検証することができます
public $validate = array(
'email' => array(
'rule' => array('isUnique', array('email', 'username'), false),
'message' => 'This username & email combination has already been used.'
)
);
複数のフィールド間で一意のルールを作成する際にフィールドのリストで元のフィールドが含まれていることを確認します。
上場フィールドがモデルデータに含まれていない場合は、、それはNULL値として扱われます。あなたは、必要に応じて、表示されたフィールドをマーキング検討することがあります。
はいといいえます。
はい、あなたはそれを自分でコーディングする必要がありますが、CakePHPの検証コンポーネント内でます。
検証コンポーネントは、カスタム検証ルールをできるようにする機構を有しています。基本的に、あなたは$の検証(通常どおりのような)内の関数名を置きます。あなたは、関数を定義する必要があります。この場合には、それが(ちょうどあなたダブルisUnique要件を適用)非常に単純です。
のhttp://book.cakephp .ORG / 2.0 / EN /モデル/データvalidation.html#カスタム検証 - ルール
の非CakePHPののソリューションを提供するために頭と肩について殴られる危険で、私は次のことを提示してみましょう。
あなたが必要しかし、多くの列の上にデータベースに一意のインデックスを作成します。
このための標準SQLの構文は次のとおりです。
create unique index {IndexName} on {Table} ({Column}, {Column}, ...)
"のtry / catch" ブロックの中にあなた "の$ this - >モデル - >保存()" コマンドを置きます。 「キャッチ」ブロックでは、エラーコードの例外をテストします。 MySQLでは、ユニークキー違反は、エラーコード23000ですが、あなたは他の可能性のあるエラーのために準備する必要があります。
これは、迅速かつ簡単だと配列括弧をカウント関与しません。
あなたはとにかく "のtry / catch" ブロック内の常にの場所のデータベース・アクセス・コード必要があります。あなたの例外処理の一部は、予期しないエラーメッセージをログ含める必要があります。あなたは、CakePHPはあなたのためのののすべてを行うことを期待することはできません。
私が覚えている限りでは、あなたは、モデル内beforeSave
メソッドを使用して施行のこの種を持っています。私は、オブジェクトがNのFKSのセットの少なくとも1つを持っている必要性があったが、私は、このようにそれを行うことができます。
編集:そこに何かが解決するかどうかを確認するためにこのスレッドを試しますあなたの問題ます。