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

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

ただいまの
回答率

90.23%

【cakephp3】DB登録処理がうまくできない(newentityした際、入力フォームのセレクトボックスの値が取得できない)

解決済

回答 1

投稿

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

beginner.tm

score 5

前提・実現したいこと

cakephp3 勉強中の初心者です。
入力フォームからデータを取得し、DBへの登録処理(register)を作成しているのですが、エラーとなりうまくいきません。
どこが誤っていてエラーとなっているのか、どのように実現すればいいのかご教示ください。よろしくお願いいたします。

自分で調べた限りでは、コントローラ内のregister()でnewEntityした際に、$memberに入力フォームのjoinyearの値が設定されていないことまではわかったのですが、なぜ値が設定されていないのか、そもそもやり方がおかしいのか、理解できていない状況です。
何卒、ご教示いただけますようよろしくお願いいたします。

コントローラー

<?php

namespace App\Controller;

//use Cake\Event\Event;
use Cake\ORM\Query;
use \Exception;
use Cake\Log\Log;
use Cake\Datasource\ConnectionManager;

class MembersController extends AppController{

~~~~ 中略 ~~~~

 public function register(){
    if ($this->request->is('post')) {
        $member = $this->Members->newEntity($this->request->data);
        if($this->Members->save($member)){
              $this->Flash->success('データの登録が完了しました');
              return $this->redirect('\members\index');//一覧へ戻る
        }else{
              $this->Flash->error('データの登録に失敗しました');
        } 
  }
    $this->set('entity',$this->Members->newEntity());
 }

~~~~ 中略 ~~~~

}

ビュー

<h1>Edit screen</h1>
<?=$this->Form->create($entity,['type'=>'post','url'=>['action'=>'register']]) ?>
<fieldset>
<?=$this->Form->input('familyname',['type'=>'text'])?>
<?=$this->Form->input('firstname',['type'=>'text'])?>
<?=$this->Form->input('sex',
                        [
                        "type" => "radio",
                        "options" => [ "1" => "男性",
                                       "2" => "女性"]
                        ]
                     );
?>
<?=$this->Form->input('dept',
                        [
                        "type" => "radio",
                        "options" => [ "1" => "総務部",
                                       "2" => "営業部"]
                        ]
                     );
?>
<?=$this->Form->input('joinyear',['type'=>'year',"minYear" => 2000,"maxYear"=>date( "Y" ) ])?>
<?=$this->Form->input('profile',
                            [
                                "type" => "textarea",
                                "label" => "profile"
                            ]
                          );
?>
</fieldset>
<?=$this->Form->button("register") ?>
<?=$this->Form->end()?>

テーブル関係

<?php
namespace App\Model\Table;

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

class MembersTable extends Table {

    public function validationDefault(Validator $validator)
    {

        $validator
            //->allowEmpty('id')
            ->notEmpty('id')
            ->integer('id');

        $validator
            ->notEmpty('familyname')
            ->ascii('familyname')
            ->minLength('familyname',2,'2文字以上入力ください。')
            ->maxLength('familyname',10,'10文字以下で入力ください。');

        $validator
            ->notEmpty('firstname')
            ->ascii('firstname')
            ->minLength('firstname',2,'2文字以上入力ください。')
            ->maxLength('firstname',10,'10文字以下で入力ください。');

        $validator
            ->notEmpty('sex')
            ->integer('sex')
            ->inlist('sex',['1','2']);

        $validator
            ->notEmpty('dept')
            ->integer('dept')
            ->inlist('dept',['1','2']);

        $validator
            ->notEmpty('joinyear');

        $validator
            ->notEmpty('profile')
            ->ascii('profile')
            ->minLength('profile',10,'10文字以上入力ください。')
            ->maxLength('profile',50,'50文字以下で入力ください。');

        return $validator;
    }
}
<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Member extends Entity {

    protected $_accessible = [
        '*' => true,
        'id' => false
    ];
}

補足情報(言語/FW/ツール等のバージョンなど)

cakePHP3.4.6
PHP5.6.30

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

まず、バリデーションエラーになった場合、エラー内容がフォームに表示されるように、$memberをentityにセットした方がいいと思います。

  public function register(){
    if ($this->request->is('post')) {
      $member = $this->Members->newEntity($this->request->data);
      if($this->Members->save($member)){
        $this->Flash->success('データの登録が完了しました');
        return $this->redirect('\members\index');//一覧へ戻る
      }else{
        $this->Flash->error('データの登録に失敗しました');
      } 
      $this->set('entity',$member);
    } else {
      $this->set('entity',$this->Members->newEntity());
    }
  }

次に、バリデーションの設定ですが、 ->notEmpty('id')は不要だと思います。フォームにidを設定する欄がない確実にエラーになると思います。自動採番ならバリデートの必要はありません。

※他にもバリデーションエラーがあれば調整してください。よくわからないのであれば、bakeコマンドを使ってコードを自動生成してみると参考になると思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/23 12:46 編集

    year型なら [joinyear] => Array ( [year] => 2000 ) が [joinyear] => 2000 になるように配列を直すのが手っ取り早いですかね

    試しにnewEntity前に以下のようなコードを追記すると上手くいきますか?
    $this->request->data['joinyear'] = $this->request->data['joinyear']['year'];

    キャンセル

  • 2017/05/23 12:52

    よく考えたら、以下のようにテンプレート側でnameを指定すればいいだけな気がしてきました。
    <?=$this->Form->input('joinyear',['type'=>'year', 'name' => 'joinyear', "minYear" => 2000,"maxYear"=>date( "Y" ) ])?>

    キャンセル

  • 2017/05/23 13:40

    ご回答ありがとうございます。
    それぞれ試してみました。

    先にご連絡いただいた配列を直す方法は、DBの更新までうまく処理できました。
    追加したコードで、joinyearの配列を直せたことも確認しています。

    次にテンプレート側でnameを指定する方法ですが、こちらはエラーとなりました。
    エラーのメッセージ等、これまでと同じで、joinyearは、 [joinyear] => Array ( [year] => 2000 )として取得されるため、newEntity時にデータを弾いてしまっています。

    いろいろご丁寧に教えてくださり、誠にありがとうございました。
    何故、このような仕様になっているのか等、若干の疑問は残りますが、
    今回は、配列を直す案で乗り切ろうと思います。
    また、自己解決が難しいような事象が発生しましたら、当サイトへ書き込ませていただきますので、
    その際は、何卒、よろしくお願いいたします。

    キャンセル

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

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • CakePHPに関する質問
  • 【cakephp3】DB登録処理がうまくできない(newentityした際、入力フォームのセレクトボックスの値が取得できない)