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

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

新規登録して質問してみよう
ただいま回答率
85.50%
CakePHP

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

Q&A

解決済

1回答

8520閲覧

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

beginner.tm

総合スコア7

CakePHP

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

0グッド

0クリップ

投稿2017/05/22 09:07

###前提・実現したいこと

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

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

###コントローラー

php

1<?php 2 3namespace App\Controller; 4 5//use Cake\Event\Event; 6use Cake\ORM\Query; 7use \Exception; 8use Cake\Log\Log; 9use Cake\Datasource\ConnectionManager; 10 11class MembersController extends AppController{ 12 13~~~~ 中略 ~~~~ 14 15 public function register(){ 16 if ($this->request->is('post')) { 17 $member = $this->Members->newEntity($this->request->data); 18 if($this->Members->save($member)){ 19 $this->Flash->success('データの登録が完了しました'); 20 return $this->redirect('\members\index');//一覧へ戻る 21 }else{ 22 $this->Flash->error('データの登録に失敗しました'); 23 } 24 } 25 $this->set('entity',$this->Members->newEntity()); 26 } 27 28~~~~ 中略 ~~~~ 29 30}

###ビュー

php

1<h1>Edit screen</h1> 2<?=$this->Form->create($entity,['type'=>'post','url'=>['action'=>'register']]) ?> 3<fieldset> 4<?=$this->Form->input('familyname',['type'=>'text'])?> 5<?=$this->Form->input('firstname',['type'=>'text'])?> 6<?=$this->Form->input('sex', 7 [ 8 "type" => "radio", 9 "options" => [ "1" => "男性", 10 "2" => "女性"] 11 ] 12 ); 13?> 14<?=$this->Form->input('dept', 15 [ 16 "type" => "radio", 17 "options" => [ "1" => "総務部", 18 "2" => "営業部"] 19 ] 20 ); 21?> 22<?=$this->Form->input('joinyear',['type'=>'year',"minYear" => 2000,"maxYear"=>date( "Y" ) ])?> 23<?=$this->Form->input('profile', 24 [ 25 "type" => "textarea", 26 "label" => "profile" 27 ] 28 ); 29?> 30</fieldset> 31<?=$this->Form->button("register") ?> 32<?=$this->Form->end()?> 33

###テーブル関係

<?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

1<?php 2namespace App\Model\Entity; 3 4use Cake\ORM\Entity; 5 6class Member extends Entity { 7 8 protected $_accessible = [ 9 '*' => true, 10 'id' => false 11 ]; 12} 13

###補足情報(言語/FW/ツール等のバージョンなど)
cakePHP3.4.6
PHP5.6.30

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

php

1 public function register(){ 2 if ($this->request->is('post')) { 3 $member = $this->Members->newEntity($this->request->data); 4 if($this->Members->save($member)){ 5 $this->Flash->success('データの登録が完了しました'); 6 return $this->redirect('\members\index');//一覧へ戻る 7 }else{ 8 $this->Flash->error('データの登録に失敗しました'); 9 } 10 $this->set('entity',$member); 11 } else { 12 $this->set('entity',$this->Members->newEntity()); 13 } 14 } 15

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

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

投稿2017/05/22 20:39

編集2017/05/22 20:40
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner.tm

2017/05/23 03:11

ご教示いただき誠にありがとうございます。 バリデーションエラー時の動きが考慮されていなかったため、 ご指摘いただいた通り、修正しました。 エラー時の対処はこれで問題ないと考えているのですが、正常系の動き(DBへの登録)がうまくいきません。以下のSQLエラーが発生してしまいます。 Error: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'joinyear' at row 1 If you are using SQL keywords as table column names, you can enable identifier quoting for your database connection in config/app.php. 実行された以下のSQLを見ると、joinyearの設定値がないため、エラーとなっているのかなと考えています。 INSERT INTO members (familyname, firstname, sex, dept, joinyear, profile) VALUES ('shimizu', 'masaki', 2, 2, '', 'registregist') 調査したところ、コントローラのregister()内で、newEntityした際($member = $this->Members->newEntity($this->request->data);)に、$memberにjoinyearが設定されていませんでした。 また、入力フォームから値が取得できているか、$this->request->dataを確認したところ、以下のように取得できているようでした。 ~略~ [dept] => 1 [joinyear] => Array ( [year] => 2000 ) ~略~ ※但し、他フィールドと異なり、データが存在する階層が異なる。 以上のことから、newEntity時にデータを弾いてしまっているとわかったのですが、対処方法がよくわからない状況です。 引き続きの質問となってしまい、誠に恐縮ですが、ご教示いただけますでしょうか。
popobot

2017/05/23 03:17

そうですね。type='year'はdateの一部なので、yearだけだとうまくいかないかもですね。joinyearはDB上の型はdateですか? intですか?
beginner.tm

2017/05/23 03:38

ご連絡ありがとうございます。 DBはmysqlを利用してまして、YEAR型で設定しています。 ↓↓↓↓↓↓desc の結果(一部)↓↓↓↓↓↓ +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | joinyear | year(4) | NO | | NULL |   | +------------+--------------+------+-----+---------+----------------+
popobot

2017/05/23 03:46 編集

year型なら [joinyear] => Array ( [year] => 2000 ) が [joinyear] => 2000 になるように配列を直すのが手っ取り早いですかね 試しにnewEntity前に以下のようなコードを追記すると上手くいきますか? $this->request->data['joinyear'] = $this->request->data['joinyear']['year'];
popobot

2017/05/23 03:52

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

2017/05/23 04:40

ご回答ありがとうございます。 それぞれ試してみました。 先にご連絡いただいた配列を直す方法は、DBの更新までうまく処理できました。 追加したコードで、joinyearの配列を直せたことも確認しています。 次にテンプレート側でnameを指定する方法ですが、こちらはエラーとなりました。 エラーのメッセージ等、これまでと同じで、joinyearは、 [joinyear] => Array ( [year] => 2000 )として取得されるため、newEntity時にデータを弾いてしまっています。 いろいろご丁寧に教えてくださり、誠にありがとうございました。 何故、このような仕様になっているのか等、若干の疑問は残りますが、 今回は、配列を直す案で乗り切ろうと思います。 また、自己解決が難しいような事象が発生しましたら、当サイトへ書き込ませていただきますので、 その際は、何卒、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問