
前提・実現したいこと
PHP(CakePHP)でユーザー管理システムを作っています。
管理画面でユーザーを追加する入力フォームで、権限の入力箇所にセレクトボックスを使っております。フォームを送信すると、以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'role' cannot be null
該当のソースコード
Model/Entity/User
<?php namespace App\Model\Entity; use Cake\ORM\Entity; /** * User Entity. * * @property int $id * @property string $name * @property string $password * @property string $role * @property \Cake\I18n\Time $endlogined */ class User extends Entity { /** * Fields that can be mass assigned using newEntity() or patchEntity(). * * Note that when '*' is set to true, this allows all unspecified fields to * be mass assigned. For security purposes, it is advised to set '*' to false * (or remove it), and explicitly make individual fields accessible as needed. * * @var array */ protected $_accessible = [ '*' => true, 'id' => false, ]; /** * Fields that are excluded from JSON an array versions of the entity. * * @var array */ protected $_hidden = [ 'password' ]; }
Model/Table/UsersTable
<?php namespace App\Model\Table; use App\Model\Entity\User; use Cake\ORM\Query; use Cake\ORM\RulesChecker; use Cake\ORM\Table; use Cake\Validation\Validator; /** * Users Model * */ class UsersTable extends Table { /** * Initialize method * * @param array $config The configuration for the Table. * @return void */ public function initialize(array $config) { parent::initialize($config); $this->table('users'); $this->displayField('name'); $this->primaryKey('id'); $this->belongsTo('Roles', [ 'foreignKey' => 'role', 'joinType' => 'INNER' ]); } /** * Default validation rules. * * @param \Cake\Validation\Validator $validator Validator instance. * @return \Cake\Validation\Validator */ public function validationDefault(Validator $validator) { $validator ->add('id', 'valid', ['rule' => 'numeric']) ->allowEmpty('id', 'create'); $validator ->requirePresence('name', 'create') ->notEmpty('name'); $validator ->requirePresence('password', 'create') ->notEmpty('password'); $validator ->requirePresence('role', 'create') ->notEmpty('role'); $validator ->add('endlogined', 'valid', ['rule' => 'datetime']) ->allowEmpty('endlogined'); return $validator; } }
Controller/Admin/UsersController
<?php namespace App\Controller\Admin; use App\Controller\AppController; use Cake\Event\Event; use Cake\ORM\Table; use Cake\ORM\TableRegistry; use Cake\Error\Debugger; class UsersController extends AppController { public function add() { $user = $this->Users->newEntity(); if ($this->request->is('post')) { $user = $this->Users->patchEntity($user, $this->request->data); if ($this->Users->save($user)) { $this->Flash->success(__('The user has been saved.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('The user could not be saved. Please, try again.')); } } $roles = $this->Users->Roles->find('list', ['limit' => 200]); $this->set(compact('user', 'roles')); $this->set('_serialize', ['user']); } }
Template/Admin/Users/add.ctp
<nav class="large-3 medium-4 columns" id="actions-sidebar"> <ul class="side-nav"> <li class="heading"><?= __('Actions') ?></li> <li><?= $this->Html->link(__('List Users'), ['action' => 'index']) ?></li> </ul> </nav> <div class="users form large-9 medium-8 columns content"> <?= $this->Form->create($user) ?> <fieldset> <legend><?= __('Add User') ?></legend> <?php echo $this->Form->input('name'); echo $this->Form->input('password'); echo $this->Form->input('role', ['options' => $roles]); ?> </fieldset> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> </div>
テーブル構成
create table roles ( role char(100) not null default 'admin', PRIMARY KEY (`role`) ); create table users ( id int unsigned not null auto_increment, name varchar(100) not null, password varchar(255) not null, role char(100) not null default 'admin', endlogined datetime default null, PRIMARY KEY (`id`), CONSTRAINT fk_role FOREIGN KEY (role) REFERENCES roles (role) ON UPDATE CASCADE ON DELETE RESTRICT );
試したこと
エラーメッセージは単純にroleカラムにNOT NULLを指定しているので、NULLを怒られているだけ。
アソシエーションで紐付けて、セレクトボックスの生成はできています。原因は、フォームで送信した値がpatchEntity()を通すとroleがNULLに変換されてしまうことだと思われます。つまり、validationDefault()に問題があるのかと思いきや、そういったおかしなバリデーションもしていないし、ということで、色々調べたりしたのですが、解決できませんでした。
みなさんのお知恵をお貸しください。よろしくお願いいたします。
問題あると思われるpatchEntityの前後の出力結果
Controller/Admin/UsersController
public function add() { $user = $this->Users->newEntity(); if ($this->request->is('post')) { Debugger::dump($this->request->data); $user = $this->Users->patchEntity($user, $this->request->data); Debugger::dump($user); exit; =====上に同じなので、省略==== }
[ 'name' => 'yamada', 'password' => 'ymymym', 'role' => 'admin' // セレクトボックスでちゃんとRolesの値が表示できていて、選択肢のうち、adminを選択して送信。 // postで送信された値はadminなのでここまでは想定通り。 ] object(App\Model\Entity\User) { 'name' => 'yamada', 'password' => 'ymymym', 'role' => null, // nullに変換される!!!!! '[new]' => true, '[accessible]' => [ '*' => true ], '[dirty]' => [ 'name' => true, 'password' => true, 'role' => true ], '[original]' => [], '[virtual]' => [], '[errors]' => [], '[repository]' => 'Users' }
補足情報(FW/ツールのバージョンなど)
CakePHP3.1.14
回答2件
あなたの回答
tips
プレビュー