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

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

ただいまの
回答率

91.87%

  • CakePHP

    1691questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Cakephp3でバリテーション

解決済

回答 1

投稿 2016/06/27 13:50

  • 評価
  • クリップ 0
  • VIEW 585

yajin

score 56

前提・実現したいこと

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/06/30 16:50

編集 2016/07/01 16:14

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2016/06/30 22:47

    ご返信ありがとうございます。
    上記の提案試してみましたが、解決できませんでした。

    何かその他に必要な情報ありますでしょうか。
    ご返信宜しくお願い致します。

    キャンセル

  • 2016/07/01 09:46

    現状は、どのような動作になっているのでしょうか?
    自分の環境では上記したように、inputタグにrequired属性が設定されているため、ブラウザが必須入力のチェックを行っていました
    また、対象画面のHTMLのソースコードでは、どのような表示になっているのでしょうか?

    キャンセル

  • 2016/07/01 13:04

    operaで見たところ次のようなエラーメッセージがあらわれました。

    Confirm form resubmission

    This webpage requires data that you entered earlier in order to be properly displayed. You can send this data again, but by doing so you will repeat any action this page previously performed. Press Reload to resend that data and display this page.
    ページの読み込みに必要なデータを再送信するには、再読み込みボタンを押してください。

    キャンセル

  • 2016/07/01 13:08 編集

    HTML上のソース

    <div class="register_form">
    <form method="post" accept-charset="utf-8" class="register_form" action="/users/register"><div style="display:none;"><input type="hidden" name="_method" value="POST"/><input type="hidden" name="_csrfToken" value="d4f31f80912c6e733062f2f91112c8bbcbf5c1aaa9b95f5497bc5afa1536d58d5dc3ee4eb452d366852ce8afcb5c9e9e33a6f527886fa27ae9f5c6afcc4078cf"/></div> <div class="input email"><label for="email">メールアドレス</label><input type="email" name="email" placeholder="メールアドレス" id="email" value=""/></div> <input type="hidden" name="ukey" value="1oYfms9o9O1bZCzcanOikeI4g_n2KA0H"/> <div class="input password"><label for="password">パスワード(8文字以上の英数字特殊文字)</label><input type="password" name="password" placeholder="パスワード" id="password" value=""/></div> <div class="input text"><label for="username">ユーザ名</label><input type="text" name="username" placeholder="ユーザ名" id="username" value=""/></div> <button type="submit">β版に同意して登録</button> </form>
    </div>

    キャンセル

  • 2016/07/01 13:11

    モデル


    namespace App\Model\Table;

    use Cake\ORM\Table;
    use Cake\Validation\Validator;



    class UsersTable extends Table{
    public function initialize(array $config)
    {
    $this->addBehavior('Timestamp');

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

    return $validator;
    }

    }

    キャンセル

  • 2016/07/01 14:39

    ソースを提示するための、元コメントに追記しましたので、ご確認ください

    キャンセル

  • 2016/07/01 16:02

    ご返信ありがとうございました。
    flashヘルパーの表示部分を記載してなかったので、記載したところ、確かにflashヘルパー(全体的なエラー表示)はできるようになったのですが、個別のエラー表示ができません。
    HTML文法チェックをしてみても、エラーはなく、タグの構造的にもあっていると考えられます。

    依然、登録はされないものの、個別のエラーメッセージはでてこず、ソースを確認しても「フォーム再送信の確認」と出てきます。

    キャンセル

  • 2016/07/01 16:05

    フォームヘルパーで、送信前のソースを確認すると、
    <div style="display:none;">がタグとしてはかれてるのですが、これが原因でしょうか?
    これを無効にできる方法はありますでしょうか?

    キャンセル

  • 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

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

    キャンセル

teratailには29人のエキスパートがいます

今すぐはじめる

もっと詳しく

関連した質問

同じタグがついた質問を見る

  • CakePHP

    1691questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

閲覧数の多いCakePHPの質問