0

I have a form, where users pick some options, and I would like to insert into DB an additional, concatenated field, based on user inputs. I need to do it on SCENARIO_CREATE (and update). E.g.:

type: A
size: 100
color: black

concatenated: A100black

I've tried it this way:

Model:

class Xyz extends BaseXyz {

    const SCENARIO_CREATE = 'create';

    public function rules() {
        ...
        ['concatenated', 'generateConcatenated', 'on' => self::SCENARIO_CREATE],

    ...

    public function generateConcatenated() {
        return $this->type . $this->size . $this->color;
    }

Controller:

class XyzController extends base\XyzController {

    public function actionCreate() {
        $model = new Xyz;
        $model->scenario = Xyz::SCENARIO_CREATE;
        ...

I've tried with 'filter' also in rules, but no success. Maybe my approach is totally wrong, and it can't be done in rules? Please point me in the right direction. Many thanks!

user2511599
  • 796
  • 1
  • 13
  • 38
  • You have two options: **1st solution** You can create hidden field for `concatenated` column in form and concatenate data from inputs type, size, color using javascript on change event (and maybe other js events) of those three inputs and set value of `concatenated` hidden field. **2nd solution** You can create method in your model which concatenates values of fields and put its result into `concatenated` field. – aslawin Mar 09 '16 at 09:49

1 Answers1

0

rules are for checking attribute validation but you can do it in rule too:

public function generateConcatenated($attribute,$param) {
    $this->concatenated = $this->type . $this->size . $this->color;
}

I think best logistic way to achieve this is to remove attribute from rules and overriding beforeSave() in your model:

public function beforeSave($insert)
{
    $this->concatenated = $this->type . $this->size . $this->color;
    return parent::beforeSave($insert);
}

you should consider that yii have default insert scenario for new record and update for existing record.

mmta41
  • 274
  • 2
  • 13
  • if I leave it so, will it in both cases do it, right? – user2511599 Mar 09 '16 at 10:51
  • If your mean of cases is scenarios then yes, because basically ActiveRecord has two scenarios `insert` and `update` until you define extra scenario your self – mmta41 Mar 09 '16 at 11:22
  • something is not okay. Is it a problem if I have already overridden beforeSave() in a Base model, and my models extend this one? `public function beforeSave($insert) { if (parent::beforeSave($insert)) { if ($insert == true) { ... } return true; } else { return false; } }` actually nothing is saved into DB. I've deleted custom scenarios, I go default now. – user2511599 Mar 09 '16 at 11:42
  • in your controller put: `if(!$model->save()) var_dump($model->getErrors());` and investigate the error – mmta41 Mar 09 '16 at 11:52
  • this is strange. I've commented a field out on the form, and Yii2 doesn't give any warnings or error messages, it simply redirects as everything would be alright. Otherwise, your suggestion works (`beforeSave()`), so thank you very much! – user2511599 Mar 09 '16 at 11:58
  • use my suggested `beforeSave` method with out any change and check the result – mmta41 Mar 09 '16 at 12:01