複数テーブルの操作(フォーム/バリデーション/コントローラー) [CakePHP]
1. 使い方
今回紹介するコードは一部抜粋です。完全なコードはオープンソースの掲示板システム(Bootstrapデザイン)をご覧ください。 ※デモはこちら
1-1. コントローラー
要となるコードは$entitiesでquestions、answersテーブルを配列で確保。
class QuestionsController extends AppController { public function add() { // カテゴリID $lang_id = $this->request->getQuery('lang_id'); if(isset($lang_id) && AppController::isNumeric($lang_id)){ $item = $this->LangTypes->find()->where(['id' => $lang_id]); if ($item->count() === 0){ return $this->redirect('/'); } $item = $item->toArray(); $lang_name = $item[0]->name; }else{ return $this->redirect('/'); } $questions = $this->Questions->newEntity(); $answers = $this->Answers->newEntity(); if ($this->request->is('post')) { // パラメータ $param = $this->request->getData(); $param['questions']['title'] = AppController::trim($param['questions']['title']); $param['answers']['name'] = AppController::trim($param['answers']['name']); $param['answers']['url'] = AppController::trim($param['answers']['url']); $param['answers']['body'] = AppController::trim($param['answers']['body']); $param['questions']['lang_type_id'] = $lang_id; $param['questions']['resolved'] = false; $param['questions']['pv'] = 0; // リクエスト(POST)の書き換え $this->request = $this->request->withData('questions.title', $param['questions']['title']); $this->request = $this->request->withData('answers.name', $param['answers']['name']); $this->request = $this->request->withData('answers.url', $param['answers']['url']); $this->request = $this->request->withData('answers.body', $param['answers']['body']); $questions = $this->Questions->patchEntity($questions, $param['questions']); $answers = $this->Answers->patchEntity($answers, $param['answers']); // コネクション $con = ConnectionManager::get('default'); // トランザクション $con->begin(); try{ // ------------------------------------------------------------ // save()ができない場合は例外(PersistenceFailedException) // ------------------------------------------------------------ // questions $this->Questions->saveOrFail($questions, ['atomic' => false]); // answers $answers['question_id'] = $questions['id']; $answers['ip'] = $this->request->clientIp(); $this->Answers->saveOrFail($answers, ['atomic' => false]); // bodies $this->body_table_update($questions['id'], false); // コミット $con->commit(); $this->Flash->success(__('登録しました。')); return $this->redirect(['action' => 'index', 'lang_id'=> $lang_id]); // ロールバック } catch (PersistenceFailedException $e) { $con->rollback(); $this->Flash->error(__('エラーをご確認ください。')); } catch (Exception $e) { // その他の例外 $con->rollback(); $this->Flash->error(__('エラーが発生しました。管理者に問い合わせてください。')); } } // 各テーブルのエンティティ $entities = [ 'questions' => $questions, 'answers' => $answers ]; $this->set(compact('lang_name')); $this->set(compact('lang_id')); $this->set(compact('entities')); } }
1-2. ビューテンプレート
Form->control()の第一引数に「テーブル名.カラム名」を設定します。
echo $this->Form->create($entities, ['type' =>'post', 'url' => $this->Url->build('/questions/add?lang_id=' . $lang_id, true), 'novalidate' => false, // ※HTML5のValidation機能 'id' => 'main_form' ]); echo $this->Form->control('questions.title', ['label' => ['text' => __('タイトル')], 'class' => 'form-control', 'required' => 'required']); echo $this->Form->control('answers.name', ['label' => ['text' => __('名前')], 'class' => 'form-control', 'required' => 'required']); echo $this->Form->control('answers.url', ['label' => ['text' => __('ホームページ(ブログ、Twitterなど)のURL (省略可)')], 'class' => 'form-control']); echo $this->Form->control('answers.body', ['label' => ['text' => __('本文')], 'class' => 'form-control','type' =>'textarea', 'required' => 'required']); echo $this->Form->button(__('作成する'), ['class' => 'btn btn-primary', 'id' => 'btn_submit', 'onclick' => 'DisableButton(this);']); echo $this->Form->end();
1-3. src/Model/Table (モデルの各テーブル)
通常通り、任意でバリデーションを設定すればOKです。
スポンサーリンク
関連記事
公開日:2021年02月11日
記事NO:02884