

cakePHP 2.4.9を使用しています。  
以下2つのテーブルをhasManyモデルを使用して結合し、追加、編集、更新を想定。

eventsテーブル

[code]

    CREATE TABLE `events` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(256) DEFAULT NULL,
      `latitude` decimal(18,15) DEFAULT NULL,
      `longitude` decimal(18,15) DEFAULT NULL,
      `adult_price` int(11) DEFAULT NULL,
      `adult_age` int(11) DEFAULT NULL,
      `child_price` int(11) DEFAULT NULL,
      `child_age` int(11) DEFAULT NULL,
      `access` text,
      `description` text,
      `minimun_participants_number` int(11) DEFAULT NULL,
      `child_policy_flag` int(11) DEFAULT NULL,
      `meals_flug` int(11) DEFAULT NULL,
      `time_of_day` int(11) DEFAULT NULL,
      `pickup_flag` int(11) DEFAULT NULL,
      `duration_hour` int(11) DEFAULT NULL,
      `pv` int(11) DEFAULT NULL,
      `rating` int(11) DEFAULT NULL,
      `created` timestamp NULL DEFAULT NULL,
      `modified` timestamp NULL DEFAULT NULL,
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
[/code]

events_schedulesテーブル

[code]

    CREATE TABLE `events_schedules` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `event_id` int(10) DEFAULT NULL,
      `title` varchar(50) DEFAULT NULL,
      `description` text,
      `start_hour` int(11) DEFAULT NULL,
      `start_min` int(11) DEFAULT NULL,
      `end_hour` int(11) DEFAULT NULL,
      `end_min` int(11) DEFAULT NULL,
      `created` datetime DEFAULT NULL,
      `modified` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
[/code]

Model/Event.php

[code]

    <?php 
    class EventController extends AppModel
    {
        public $hasMany = array(
            'Event' => array(
                'className' => 'Event',
                'foreignKey' => 'event_id',
                'dependent' => true,
                'conditions' => '',
                'fields' => '',
                'order' => '',
                'limit' => '',
                'offset' => '',
                'exclusive' => '',
                'finderQuery' => '',
                'counterQuery' => '',
            ),
        );
    }
    
[/code]

となっており、一つのイベントIDにつき複数のスケジュールを追加できるようにしています。  
コントローラー側の処理です。  
Controller/EventController.php

[code]

    <?php
    App::uses('AppController', 'Controller');
    App::uses('HttpSocket', 'Network/Http');
    
    class EventsController extends AppController
    {
    
        public $uses = array('Event', 'EventSchedule');
    
        public function edit($id = null)
        {
            if ($this->request->is('Event') || $this->request->is('post')) {
                if ($id == null) {
                    $id = $this->Event->getLastInsertID();
                } else {
                    $this->EventSchedule->deleteAll(array('EventSchedule.event_id' => $id));
                }
                $this->Event->id = $id;
    
                if ($this->Event->save($this->request->data)) {
                    if ($this->request->data('EventsSchedule')) {
                        $this->EventsSchedule->saveAll($this->request->data['EventsSchedule'], array('deep' => true));
                    }
                    {
                        $this->Flash->success(__('登録が完了しました'));
                    }
    
                    $this->redirect(array('action' => 'edit', $this->Event->id));
                } else {
                    $this->Flash->error(__('失敗しました'));
                }
            }
    
            $options = array('conditions' => array('Event.id' => $id));
            $this->request->data = $this->Event->find('first', $options);
            $this->set('event', $this->request->data);
        }
    
[/code]

View側では複数のインプットを保存できるように用意  
View/Events/edit.ctp

[code]

    <?php echo $this->Form->create('Event', array('type' => 'button', 'action' => 'edit','div' => false)); ?>
        （中略）
        .
        .
        .
        <?php 
        $count = 0; 
        foreach($this->data['EventsSchedule'] as $Eventschedule): ?> 
            <tr>
                <th rowspan="8">スケジュール</th>
                <td>
                    <div class="form-inline">
                        <div class="ui two fields">
                            <div class="form-group">
                                <label>日本語</label>
                                <?php echo $this->Form->input('EventsSchedule.'. $count . '.title', array('type' => 'text', 'placeholder' => 'スケジュールタイトル(日本語)', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)) ;?>
                            </div>
                            <div class="form-group">
                                <label>詳細</label>
                                <?php echo $this->Form->input('EventsSchedule.'. $count . '.description', array('type' => 'text', 'placeholder' => 'スケジュール詳細(日本語)', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)) ;?>
                            </div>
                        </div>
                    </div>
                </td>
            </tr>
            <tr>
                <td>
                    <div class="form-inline">
                        <div class="ui fields">
                            <div class="form-group">
                                <label>開始時間</label>
                                <?php echo $this->Form->input('EventsSchedule.'.$count. '.start_hour',array('type' => 'select','options' => Configure::read('Hour.codes'),'class' => 'select', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)); ?>：
                                <?php echo $this->Form->input('EventsSchedule.'.$count. '.start_min', array('type' => 'select','options' => Configure::read('Minute.codes'),'class' => 'select', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)); ?> 〜 
                            </div>
                            <div class="form-group">
                                <label>終了時間</label> 
                                <?php echo $this->Form->input('EventsSchedule.'.$count. '.end_hour',array('type' => 'select','options' => Configure::read('Hour.codes'),'class' => 'select', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)); ?>：
                                <?php echo $this->Form->input('EventsSchedule.'.$count. '.end_min', array('type' => 'select','options' => Configure::read('Minute.codes'),'class' => 'select', 'div' => false, 'label' => false, 'class' => 'form-control', 'required' => false)); ?>
                            </div>
                        </div>
                    </div>
                </td>
            </tr>
        <?php $count++; ?>
        <?php endforeach; ?>
    <?php echo $this->Form->end(array('label' => '登録・編集', 'class' => 'btn btn-primary')); ?>
    
[/code]

ここまではなんとかで用意でき、以下のことが実現できません。  
・更新を押した際にEvents_scheduleテーブルにevent_idが保存されない  
・スケジュールの入力欄を動的に追加できるようにしたい

どなたかご教示いただけると幸いです。  
宜しくお願い致します。


CC BY-SA 3.0
2016-03-22T02:31:59.297
23330
2016-04-24T01:30:52.403
2016-03-23T04:03:13.903
8500
8500
question
cakephp
CakePHPでhasManyを使った更新が上手くいかない


いろいろと例示コード上におかしな点がありますが、保存部分だけに絞って回答します。

`EventsController::edit()`において`$this->Event->save()`の後に`$this->EventSchedule->saveAll()`を実行していますが、これはまとめて`saveAssociated`を使いましょう。

<http://book.cakephp.org/2.0/ja/models/saving-your-data.html#model-
saveassociated-array-data-null-array-options-array>

[code]

    if ($this->Event->saveAssociated($this->request->data)) {
        // 保存成功時の処理
    } else {
        // 保存失敗時の処理
    }
    
[/code]

また、View側でEvendScheduleのidが指定されていないため、このままではEventScheduleレコードが毎回新規作成されてしまいます。

そこで、View側で

[code]

    <?php
    foreach($this->request->data['EventsSchedule'] as $count => $Eventschedule): ?> 
        <tr>
            <th rowspan="8">スケジュール</th>
            <td>
              <?php echo $this->Form->hidden("EventsSchedule.$count.id"); ?>
    
[/code]

のようにして、EventsSchedule.idをhiddenでセットしておきます。

（foreachループで$countをインクリメントしていますが、このようにforeachでキーとして取得すればインクリメントは不要ですよね。）


CC BY-SA 3.0
2016-03-25T01:03:12.407
23435
2016-03-25T01:03:12.407
2668
23330
answer