前提・実現したいこと
・登録フォームを用意(対象のinputはnameとかで)
・ng_wordテーブルに設定した言葉をバリデーションしたい
1.テーブルに単語を登録
2.ControllerのinitializeでTableRegistryを使用してng_wordEntityを取得
3.Actionで $this->set('ngword', $this->ngwords->find())
Controller
public function register($lang = null)
{
$lang = ($lang === null) ? 'ja' : $lang;
$dataMaster = new DataMaster();
$this->set('Countries', $dataMaster->getAllCountries($lang));
$this->set('Languages', $dataMaster->getAllLanguages($lang));
$this->set('Genders', $dataMaster->getAllGenders($lang));
if ($lang === 'ja') {
$this->set('Prefectures', $dataMaster->getAllPrefectures($lang));
}else{
$this->set('Prefectures', false);
}
$member = $this->Member->newEntity();
if ($this->request->is('post')) {
$member = $this->Member->newEntity($this->request->data, [
'associated' => ['MemberDetail']
]);
if ($member->errors()){
$this->Flash->error(__('The member could not be saved. Please, try again.'));
}
if ($this->Member->save($member)) {
$this->Flash->success(__('The member has been saved.'));
return $this->redirect(['action' => 'login']);
}
}
$this->set(compact('member'));
$this->set('_serialize', ['member']);
}
$ngWords = $this->ngwords->find();
foreach ($ngWords as $row){
$word[] = $row->word;
}
$this->set('ngwords', $word);
Table
public function validationDefault(Validator $validator)
{
$validator
->allowEmpty('id', 'create');
$validator
->allowEmpty('nickname')
->add('nickname', [
'ngword' => [
'rule' => function($value, $context){
return !TableRegistry::get('ng_word')->exists(["'{$value}' LIKE concat('%', word, '%')"]);
},
'massage' => '「おなまえ」に不適切な語句が含まれています'
]
]);
$validator
->integer('gender')
->notEmpty('gender');
$validator
->date('birthday')
->allowEmpty('birthday');
$validator
->integer('country')
->allowEmpty('country');
$validator
->integer('prefecture')
->allowEmpty('prefecture');
$validator
->integer('language')
->allowEmpty('language');
$validator
->allowEmpty('created_by');
$validator
->dateTime('created_at');
$validator
->allowEmpty('updated_by');
$validator
->dateTime('updated_at');
return $validator;
}
Template
<div class="member form large-9 medium-8 columns content">
<?= $this->Form->create($member) ?>
<fieldset>
<legend><?= __('新規会員登録') ?></legend>
<p>全項目入力して下さい</p>
<?php
echo $this->Form->input('member_detail.0.nickname', ['label' => __('なまえ')]);
echo $this->Form->input('member_detail.0.gender', ['label' => __('性別'), 'type' => 'radio', 'options' => $Genders]);
echo $this->Form->input('member_detail.0.birthday', ['label' => __('生年月日'), 'type' => 'date', 'dateFormat' => 'YMD', 'monthNames' => false, 'maxYear' => date('Y'), 'minYear' => 1850, 'empty' => '---']);
echo $this->Form->input('member_detail.0.country', ['label' => __('国籍'), 'type' => 'select', 'options' => $Countries]);
if ($Prefectures) {
echo $this->Form->input('member_detail.0.prefecture',
['label' => __('都道府県'), 'type' => 'select', 'options' => $Prefectures]);
}
echo $this->Form->input('member_detail.0.language', ['label' => __('言語'), 'type' => 'select', 'options' => $Languages]);
echo $this->Form->input('mail_address', ['label' => __('メールアドレス'), 'type' => 'email']);
echo $this->Form->input('login_id', ['label' => __('ログインID'), 'type' => 'text']);
echo $this->Form->input('login_password', ['label' => __('パスワード'), 'type' => 'password']);
echo $this->Form->hidden('is_active', ['default' => 1]);
echo $this->Form->hidden('is_deleted', ['default' => 0]);
?>
</fieldset>
<?= $this->Form->button(__('確認')) ?>
<?= $this->Form->end() ?>
</div>
ここからどうして良いか分かりません。
カスタムバリデーションの作成や取得したデータをそこに反映させる方法等・・
補足情報(言語/FW/ツール等のバージョンなど)
php7.1.1 / cake PHP3.3.12/
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
カスタムバリデートで、バリデート関数内でng_wordテーブルにアクセスすればいいと思います。
以下、サンプルです。
public function validationDefault(Validator $validator) {
$validator
->add('name', [
'ngword' => [
'rule' => function($value, $context) {
return !TableRegistry::get('ng_word')->exists(["'{$value}' LIKE concat('%', word, '%')"]);
},
'message' => 'NGワードが含まれています'
],
]);
return $validator;
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.13%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/02/08 14:44 編集
是非参考にさせて頂きます。
ちなみにここで設定したmassageはどのタイミングで表示されるのでしょうか?
debugで見てみるとerrors()の中には `name = "The provided value is invalid"` とあります。
バリデーションが実行されるのはEntityの作成時だと思いますが、今回はアソシエーションしている別Tableでこのバリデーションを行っているので、newEntityをするTableには含まれておらず、バリデーションはかかっているようなのですがメッセージが表示されません。
2017/02/08 15:27 編集
2017/02/08 16:29
気になっているのは$member->errors()で取れるエラーメッセージがカスタムで設定したmassageではなくvalidator.phpの_processRulesに記載されているものになっていることです。
2017/02/08 19:28
2017/02/09 14:19
returnされないパスとはどういったものでしょうか?
2017/02/09 14:26
関数がreturnで終わっていないものです。例えば以下の関数だと$isHogeがfalseだと関数の最後までいきますが、関数の最後でreturnしていないとreturn nullと同じことになります。
function() {
if($isHoge) {
return false;
}
}
2017/02/09 14:28
2017/02/09 15:50
2017/02/09 16:04 編集
2017/02/09 16:11
修正したところ$member->errors()のmessageには入っていますが、ブラウザ表示は未だにされません。
2017/02/09 16:20
2017/02/09 16:20
しかし、一度に複数のバリデーションエラーが発生した時に対応できません。
どうするのが一般的なのでしょうか。
2017/02/09 16:21
2017/02/09 16:30
2017/02/09 16:31
createの第一引数に入れる方法を試してみます。
2017/02/09 16:49
この状態でも駄目なのですがどこがおかしいでしょうか・・
2017/02/09 17:02
アソシエーション以外のデータのエラーメッセージはでるのでしょうか
バリデート失敗時には、入寮した値はinputに入っていますか
2017/02/09 17:23
原因はTemplateのcreate()第一引数の記述かと思われます。
$this->Form->create('member')と書いていたのですが
$this->Form->create($member)に修正することで動作しました。
本文のコードを動作確認状態に修正してあります。
errorがあった場合はsaveは失敗するのでリダイレクトもされませんが、この書き方は良くないでしょうか。
修正前の時点ではアソシエーション以外のデータのエラーメッセージも出ませんでした。
バリデート失敗時にはinputに値は入っていました。
2017/02/09 17:34
> errorがあった場合はsaveは失敗するのでリダイレクトもされませんが、この書き方は良くないでしょうか。
別に大丈夫ですが、error()があったら$this->Flash->error()の後にreturnしちゃった方がわかりやすいかと
2017/02/09 18:53
errorのあとはreturn ;で終わらせることにします。
長々とお付き合い頂きありがとございました!。。