5

I have an annoying problem, using latest OctoberCMS build (318), where it tries to save the wrong data to the pivot table instead of model table.

I have a model Businesses, and a model Openinghours:

Model for Businesses:

`public $table = 'ekstremedia_emcityportal_businesses';`
`public $belongsToMany = [
    'openinghours' => [
            'Ekstremedia\EmCityportal\Models\Openinghours',
            'table' => 'ekstremedia_emcityportal_ohb',
            'order' => 'week_day',
            'week_day' => 'week_day',
            'name' => 'week_day',
    ]           
];`    

ekstremedia_emcityportal_ohb is the pivot table with business_id and openinghours_id

And model for Openinghours:

public $table = 'ekstremedia_emcityportal_openinghours';
public $belongsToMany = [
        'businesses' => ['Ekstremedia\EmCityportal\Models\Business',
        'table' => 'ekstremedia_emcityportal_businesses',
        'order' => 'created_at desc'       
  ]
];   

In the Business controllers field.yaml i have done this, to add opening hours to a business:

    openinghours:
        type: repeater
        label: 'Åpningstider'
        tab: 'Åpningstider'
        form:
            fields:
                week_day:
                    label: Dag
                    oc.commentPosition: ''
                    options:
                        1: Måndag
                        2: Tysdag
                        3: Onsdag
                        4: Torsdag
                        5: Fredag
                        6: Laurdag
                        7: Sundag
                    span: left
                    type: dropdown
                open_hour:
                    label: Date added
                    type: datepicker
                    mode: time
                close_hour:
                    mode: time
                    label: Date added
                    type: datepicker

The problem is, october is trying to save the opening hours to the pivot table and not the model table. Anyone have an idea how i can fix that? Ive tried alot of different options. .

This is the error i get on the backend:

 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'close_hour' in 'field list' (SQL: insert into 'ekstremedia_emcityportal_ohb' ('business_id', 'close_hour', 'open_hour', 'openinghours_id', 'week_day')...

close_hour, open_hour, openinghours_id, week_day etc, is in ekstremedia_emcityportal_openinghours , defined in Openinghours model, not in ekstremedia_emcityportal_ohb wich is the pivot table...

Terje Nesthus
  • 810
  • 3
  • 12
  • 30

2 Answers2

1

hi i think that your case is a complex relation scenario and for that october cms as a tool to handle this for your it is the relation behavior in fact form behavior is enough for simple relation or when you link thinks AFTER you have created them.

Here you are trying to create an save both at the same time. there is a pretty good ressource about it and i think it is enough to understand relation behavior.

But does openinghours belong to more than one business ?

Greg Bee
  • 144
  • 1
  • 6
0

Your bug is normal behavior of October default form saver.

By default for auto generated form for save october use trait Backend\Traits\FormModelSaver. That thait can work only with:

  • 'belongsTo'
  • 'hasOne'
  • 'morphOne'

You can redefined save method to allow october work with your model. For example I redefine create:

namespace Local\Test\Controllers;

class Business extends Controller
{
        use \Backend\Traits\FormModelSaver;

        public $implement = ['Backend\Behaviors\ListController','Local\Test\Controllers\FormController'];
}

namespace Local\Test\Controllers;

use Backend\Behaviors\FormController as BaseFormController;
use Local\Test\Models\Openinghours;
use Flash;

class FormController extends BaseFormController
{
    /**
     * Ajax handler for saving from the creation form.
     * @return mixed
     */
    public function create_onSave($context = null)
    {
        $this->context = strlen($context) ? $context : $this->getConfig('create[context]', self::CONTEXT_CREATE);
        $model = $this->controller->formCreateModelObject();
        $this->initForm($model);

        $this->controller->formBeforeSave($model);
        $this->controller->formBeforeCreate($model);

        $savedData = $this->formWidget->getSaveData();
        $openHours = $savedData['openinghours'];
        unset($savedData['openinghours']);
        $modelsToSave = $this->prepareModelsToSave($model, $savedData);

        foreach ($modelsToSave as $modelToSave) {
            $modelToSave->save(null, $this->formWidget->getSessionKey());
        }

        foreach ($openHours as $formOpeninghours ) {
            $oph = new Openinghours();
            $oph->week_day = $formOpeninghours['week_day'];
            $oph->open_hour = $formOpeninghours['open_hour'];
            $oph->close_hour = $formOpeninghours['close_hour'];
            $model->openinghours()->save($oph);
        }

        $this->controller->formAfterSave($model);
        $this->controller->formAfterCreate($model);

        Flash::success($this->getLang('create[flashSave]', 'backend::lang.form.create_success'));

        if ($redirect = $this->makeRedirect('create', $model)) {
            return $redirect;
        }
    }
}
Pawel
  • 21
  • 3
  • Ok, but would the open hours items still show and be editable in the backend? – Terje Nesthus Apr 08 '16 at 23:37
  • As I understand you ask now about update records. If you change update_onSave action by analogy of create_onSave, october can update records. For view, you can use partial template, that allow you show data that you need. – Pawel Apr 09 '16 at 13:22