前提・実現したいこと
cakePHP3にて、一つの登録フォームで複数テーブル(アソシエーション)に保存したい。
発生している問題・エラーメッセージ
The member could not be saved. Please, try again.
(Controllerの保存処理エラー)
該当のソースコード
MemberController
public function register()
{
$member = $this->Member->newEntity();
if ($this->request->is('post')) {
$member = $this->Member->newEntity($this->request->data, [
'associated' => ['MemberDetail']
]);
if ($this->Member->save($member)) {
$this->Flash->success(__('The member has been saved.'));
return $this->redirect(['action' => 'login']);
}
$this->Flash->error(__('The member could not be saved. Please, try again.'));
}
$this->set(compact('member'));
$this->set('_serialize', ['member']);
}
MemberTable
class MemberTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->addBehavior('Timestamp', [
'events' => [
'Model.beforeSave' => [
'created_at' => 'new',
'updated_at' => 'existing',
]
]
]);
$this->table('member');
$this->displayField('id');
$this->primaryKey('id');
$this->hasMany('AmusementPointHistory', [
'foreignKey' => 'member_id'
]);
$this->hasMany('MemberDetail', [
'foreignKey' => 'member_id'
]);
$this->hasMany('MemberDevice', [
'foreignKey' => 'member_id'
]);
$this->hasMany('TrophyAcquireHistory', [
'foreignKey' => 'member_id'
]);
$this->belongsToMany('Card', [
'foreignKey' => 'member_id',
'targetForeignKey' => 'card_id',
'joinTable' => 'member_card'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->allowEmpty('id', 'create');
$validator
->requirePresence('login_id', 'create')
->notEmpty('login_id')
->add('login_id', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->requirePresence('login_password', 'create')
->notEmpty('login_password');
$validator
->requirePresence('mail_address', 'create')
->notEmpty('mail_address')
->add('mail_address', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->allowEmpty('remainder_hash');
$validator
->dateTime('last_login_at')
->allowEmpty('last_login_at');
$validator
->integer('is_active')
->requirePresence('is_active', 'create')
->notEmpty('is_active');
$validator
->allowEmpty('admin_memo');
$validator
->integer('is_deleted')
->requirePresence('is_deleted', 'create')
->notEmpty('is_deleted');
$validator
->allowEmpty('created_by');
$validator
->dateTime('created_at')
->requirePresence('created_at', 'create')
->notEmpty('created_at');
$validator
->allowEmpty('updated_by');
$validator
->dateTime('updated_at')
->requirePresence('updated_at', 'create')
->notEmpty('updated_at');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['login_id']));
$rules->add($rules->isUnique(['mail_address']));
return $rules;
}
public function updateLastLoginAt($user)
{
$data = $this->get($user['id']);
$data->last_login_at = Time::now();
$this->save($data);
}
}
MemberDetailTable
public function initialize(array $config)
{
parent::initialize($config);
$this->addBehavior('Timestamp', [
'events' => [
'Model.beforeSave' => [
'created_at' => 'new',
'updated_at' => 'existing',
]
]
]);
$this->table('member_detail');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Member', [
'foreignKey' => 'member_id',
'joinType' => 'INNER'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->allowEmpty('id', 'create');
$validator
->allowEmpty('nickname');
$validator
->integer('gender')
->allowEmpty('gender');
$validator
->date('birthday')
->allowEmpty('birthday');
$validator
->integer('country')
->allowEmpty('country');
$validator
->integer('prefecture')
->allowEmpty('prefecture');
$validator
->integer('language')
->allowEmpty('language');
$validator
->allowEmpty('created_by');
$validator
->dateTime('created_at')
->requirePresence('created_at', 'create')
->notEmpty('created_at');
$validator
->allowEmpty('updated_by');
$validator
->dateTime('updated_at')
->requirePresence('updated_at', 'create')
->notEmpty('updated_at');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['member_id'], 'Member'));
return $rules;
}
register.ctp
<div class="member form large-9 medium-8 columns content">
<?= $this->Form->create($member) ?>
<fieldset>
<legend><?= __('新規会員登録') ?></legend>
<?php
echo $this->Form->input('member_detail.0.nickname');
echo $this->Form->select('member_detail.0.gender', [0, 1, 2]);
echo $this->Form->input('member_detail.0.birthday', ['type' => 'date']);
echo $this->Form->select('member_detail.0.country', [1, 2, 3, 4, 5]);
echo $this->Form->select('member_detail.0.prefecture', [1, 2, 3, 4, 5]);
echo $this->Form->select('member_detail.0.language', [1, 2, 3, 4, 5]);
echo $this->Form->input('mail_address', ['type' => 'email']);
echo $this->Form->hidden('login_id', ['type' => 'text']);
echo $this->Form->input('login_password', ['type' => 'password']);
echo $this->Form->hidden('remainder_hash');
echo $this->Form->hidden('last_login_at', ['empty' => true]);
echo $this->Form->hidden('is_active');
echo $this->Form->hidden('admin_memo');
echo $this->Form->hidden('is_deleted');
echo $this->Form->hidden('created_by');
echo $this->Form->hidden('created_at');
echo $this->Form->hidden('updated_by');
echo $this->Form->hidden('updated_at');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
試したこと
Viewのバリデーションで引っかかっているのかと思い、入力させたくないフィールドを削除したのですが、変わりませんでした。
補足情報(言語/FW/ツール等のバージョンなど)
php7.1.1 / cake PHP3.3.12/
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
バリデートで色々エラーが出ているかだと思いますよ。
save()を実行する前にはバリデートでエラーが出ていないかerrors()を見るべきです。エラーがあるならsave()は実行せずにreturnして入力画面に戻したらいいと思います。
※newEntityで内部的にはバリデーションが自動的に実行されerrors()でバリデーションの結果が閲覧できます。
ただ、現状発生しているのはhiddenなものが多いですね... バリデーションが適切か見直してください。特にユーザが入力しない項目ならinput自体やめて、バリデートもやめちゃってもいい気がしました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
popobot
2017/02/07 11:41 編集
saveの直前でdebug($member->errors());を実行すると何か表示されますか? debug($member);を見てみるのもいいと思いますよ。
sbc
2017/02/07 11:42
やってみます!
この投稿は削除されました