ホーム > カテゴリ > PHP・Laravel・CakePHP >

複数テーブルの操作(フォーム/バリデーション/コントローラー) [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