1

In my controllers that Gii creates it is common to see the following:

if($model->load(Yii::$app->request->post()) && $model->save()){
//.....do something such as redirect after save....//
}else
{
//.....render the form in initial state.....//
}

This works to test whether a POST is sent from my form && the model that I am specifying has saved the posted information (as I understand it).

I've done this similarly in controllers that I have created myself but in some situations this conditional gets bypassed because one or both of these conditions is failing and the form simply gets rendered in the initial state after I have submitted the form and I can see the POST going over the network.

Can someone explain why this conditional would fail? I believe the problem is with the 'Yii::$app->request->post()' because I have removed the '$model->save()' piece to test and it still bypasses the conditional.

Example code where it fails in my controller:

public function actionFreqopts()
{

    $join = new FreqSubtypeJoin();
    $options = new Frequency();
    $model = new CreateCrystal();
    if ($model->load(Yii::$app->request->post()) && $model->save()) {

        $model->insertFreqopts();
        return $this->redirect(['fieldmap', 'id' => $join->id]);
    } else {
        return $this->render('freqopts', ['join' => $join, 'options' => $options]); 
    }
}

My initial thought was that I'm not specifying the correct "$model" in that I'm trying to save the posted data to FreqSubtypeJoin() in this case and the $model is CreateCrystal(); however, even when I change the model in this conditional it still fails. It would be helpful if someone could briefly explain what the method 'load' is actually doing in layman's terms if possible.

tereško
  • 58,060
  • 25
  • 98
  • 150
Scott
  • 107
  • 1
  • 1
  • 15

1 Answers1

0

The load() method of Model class is basically populating the model with data from the user, e.g. a post query.

To do this it firstly loads your array of data in a form that matches how Yii stores your record. It assumes that the data you are trying to load is in the form

_POST['Model name']['attribute name']

This is the first thing to check, and, as long as your _POST data is actually getting to the controller, is often where load() fails, especially if you've set your own field names in the form. This is why if you change the model, the model will not load.

It then check to see what attributes can be massively assigned. This just means whether the attributes can be assigned en-mass, like in the $model->load() way, or whether they have to be set one at a time, like in

$model->title = "Some title";

To decide whether or not an attribute can be massively assigned, Yii looks at your validation rules and your scenarios. It doesn't validate them yet, but if there is a validation rule present for that attribute, in that scenario, then it assumes it can be massively assigned.

So, the next things to check is scenarios. If you've not set any, or haven't used them, then there should be no problem here. Yii will use the default scenario which contains all the attributes that you have validation rules for. If you have used scenarios, then Yii will only allow you to load the attributes that you have declared in your scenario.

The next thing to check is your validation rules. Yii will only allow you to massively assign attributes that have associated rules.

These last two will not usually cause load() to fail, you will just get an incomplete model, so if your model is not loading then I'd suggest looking at the way the data is being submitted from the form and check the array of _POST data being sent. Make sure it has the form I suggested above.

I hope this helps!

Joe Miller
  • 3,843
  • 1
  • 23
  • 38
  • This is very helpful! Thank you for the thoughtful response. I did change the names so I'm sure that is the issue, but I could also see how the validation rules could trip it up too particularly if I'm using a "view model" that pulls in a bunch of base models without handling those properties and rules correctly. – Scott Dec 25 '15 at 21:28
  • Hope it works out @Scott. When you've had a chance to test it, if the answer worked for you it would be useful if you could accept the answer so that other users can see what was the best answer. Thanks! – Joe Miller Dec 26 '15 at 05:38