質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.23%

Cakephp3でバリテーション

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,009

yajin

score 73

前提・実現したいこと

CakePHP3でユーザ仮登録のバリテーションをかけようと思っています。
フォームに正しくない値を挿入すると、リダイレクトはされずにいますが、エラーメッセージが表示されません。

発生している問題・エラーメッセージ

エラーメッセージが表示されない。
一度、登録ボタンを押すとソースが表示されなくなる。(chrome)

該当のソースコード

UsersTable.php

public function validationDefault(Validator $validator)
  {
         $validator
            ->notEmpty('email', 'メールアドレスが入力されていません。')
            ->notEmpty('password', 'パスワードが入力されていません。')
            ->notEmpty('username', 'ニックネームが入力されていません。')
            ->add('password',[
            'length'=> [
        'rule' => ['minLength', 8],
        'message' => 'パスワードは8文字以上で設定してください。'
      ]
    ]);

            return $validator;
  }
<?= $this->Form->create('user',['class' => 'register_form']); ?>
        <?= $this->Form->input('email',['label' => 'メールアドレス','placeholder' => 'メールアドレス']); ?>
        <?= $this->Form->hidden('ukey',['value' => strtr(substr(base64_encode(openssl_random_pseudo_bytes(32)),0,32),'/+','_-')]); ?>
        <?= $this->Form->input('password',['label' => 'パスワード','placeholder' => 'パスワード']); ?>
        <?= $this->Form->input('username',['label' => 'ユーザ名','placeholder' => 'ユーザ名']); ?>
        <?= $this->Form->button('登録'); ?>
        <?= $this->Form->end(); ?>

試したこと

そもそもctpファイルに出力するためにどのように書けばよいのでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • KatsumiTanaka

    2016/06/28 16:43

    類似質問が解決済みですが、これは参照されましたか?
    https://teratail.com/questions/26691

    キャンセル

  • yajin

    2016/06/30 00:09

    はい。参照しました。inputで書いています。

    キャンセル

回答 1

checkベストアンサー

0

状況が、あまり把握できていませんが、ModelのValidatorにnotEmptyの条件を追加することで、FormヘルパーによるInput生成の際に、HTMLのrequired属性が設定されてしまのが原因のように思います
required属性が設定されると、ブラウザ側で未入力のチェックが行われ、自分の環境(Chrome)では「このフィールドを入力してください」とポップアップのようなメッセージが表示されます

このrequired属性が自動で設定されてしまうのは、以下のようにFormヘルパーのinputメソッドのオプションで、requiredをFalse設定することにより回避できます
このとき、対象フィールドは未入力のままPOSTされますので、、サーバ側のバリデーションで未入力を検出し、設定したメッセージを表示することが可能になります

<?= $this->Form->input('password',['required' => false,'label' => 'パスワード','placeholder' => 'パスワード']); ?>

【追記2016/07/01】
自分の環境は、テーブルを作成してcontroller,model,templateをbakeしたのち、バリデーションの条件のみを追加していますが、問題なくエラーメッセージが表示されます
自分の環境のコード(といってもほとんどbakeしたままですが)を添付しますので、ご自身のコードとの差分等をご確認ください

コントローラー
/**
 * Samples Controller
 *
 * @property \App\Model\Table\SamplesTable $Samples
 */
class SamplesController extends AppController
{

    /**
     * Add method
     *
     * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise.
     */
    public function add()
    {
        $sample = $this->Samples->newEntity();
        if ($this->request->is('post')) {
            $sample = $this->Samples->patchEntity($sample, $this->request->data);
            if ($this->Samples->save($sample)) {
                $this->Flash->success(__('The sample has been saved.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The sample could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('sample'));
        $this->set('_serialize', ['sample']);
    }
}

モデル
/**
 * Samples Model
 *
 */
class SamplesTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('samples');
        $this->displayField('name');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');
        $validator
            ->notEmpty('name', '名前を入力してください')
            ->notEmpty('comment','コメントを入力してください')
            ->add('comment',['length'=> ['rule' => ['minLength', 8],'message' => 'コメントは8文字以上で設定してください']]);

        return $validator;
    }
}

テンプレート(addのみ)
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('List Samples'), ['action' => 'index']) ?></li>
    </ul>
</nav>
<div class="samples form large-9 medium-8 columns content">
    <?= $this->Form->create($sample) ?>
    <fieldset>
        <legend><?= __('Add Sample') ?></legend>
        <?php
            echo $this->Form->input('name',['required' => false, 'label' => '名前','placeholder' => '名前']);
            echo $this->Form->input('comment',['required' => false, 'label' => 'コメント', 'placeholder' => 'コメント']);
        ?>
    </fieldset>
    <?= $this->Form->button(__('Submit')) ?>
    <?= $this->Form->end() ?>
</div>

【追記】
画面のHTMLソース

<div class="samples form large-9 medium-8 columns content">
    <form method="post" accept-charset="utf-8" action="/cakephp30/samples/add">
    <div style="display:none;">
        <input type="hidden" name="_method" value="POST"/>
    </div>
    <fieldset>
        <legend>Add Sample</legend>
        <div class="input text required">
            <label for="name">Name</label>
            <input type="text" name="name" required="required" maxlength="45" id="name"/>
        </div>
        <div class="input text">
            <label for="comment">Comment</label>
            <input type="text" name="comment" maxlength="45" id="comment"/>
        </div>
    </fieldset>
    <button type="submit">Submit</button>
    </form>
</div>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/01 16:16

    元コメントに自分の環境のHTMLソースを追記しましたが、
    <div style="display:none;">
    は、同じように出力されているので、問題ないと思います

    キャンセル

  • 2016/07/01 17:59

    色々といじっていたら解決できました。
    formヘルパーの第一引数を$userにして、$this->Form->error('Model.email)などと設定したところ、表示されるようになりました。
    ありがとうございます。

    キャンセル

  • 2016/07/01 18:03

    解決できてよかったです(・∀・)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる