Relational attribute in Yii2 form

Ric picture Ric · Dec 3, 2014 · Viewed 10k times · Source

I am trying to get to figure out the proper way of handling a form receiving relational data in Yii2. I haven't been able to find any good examples of this. I have 2 models Sets and SetsIntensity, every Set may have one SetsIntensity associated with it. I'm am trying to make a form where you can input both at the same time. I'm not sure how to handle getting the input for a particular field 'intensity' in SetsIntensity.

Where

$model = new \app\models\Sets();

If I put it in the field like this client validation won't work and the attribute name is ambiguous and saving becomes difficult

<?= $form->field($model, 'lift_id_fk') ?>
<?= $form->field($model, 'reps') ?>
<?= $form->field($model, 'sets') ?>
<?= $form->field($model, 'type') ?>
<?= $form->field($model, 'setsintensity') ?>

I would like to do something like this but I get an error if I do

<?= $form->field($model, 'setsintensity.intensity') ?>
Exception (Unknown Property) 'yii\base\UnknownPropertyException' with message 'Getting unknown property: app\models\Sets::setsintensity.intensity'

I could do make another object in the controller $setsintensity = new Setsintensity(); but I feel this is a cumbersome solution and probably not good practice especially for handling multiple relations

<?= $form->field($setsintensity, 'intensity') ?>

relevant code from SetsModel

class Sets extends \yii\db\ActiveRecord
{

    public function scenarios() {
        $scenarios = parent::scenarios();
        $scenarios['program'] = ['lift_id_fk', 'reps', 'sets', 'type', 'intensity'];
        return $scenarios;
    }

public function rules()
{
    return [
        [['lift_id_fk'], 'required'],
        [['lift_id_fk', 'reps', 'sets','setsintensity'], 'integer'],
        [['type'], 'string', 'max' => 1],
        ['intensity', 'safe', 'on'=>'program']
    ];
}
public function getSetsintensity()
{
    return $this->hasOne(Setsintensity::className(), ['sets_id_fk' => 'sets_id_pk']);
}

SetsIntensity Model

class Setsintensity extends \yii\db\ActiveRecord
{

    public static function tableName()
    {
        return 'setsintensity';
    }

    public function rules()
    {
        return [
            [['sets_id_fk', 'intensity', 'ref_set'], 'required'],
            [['sets_id_fk', 'intensity', 'ref_set'], 'integer']
        ];
    }

    public function getSetsIdFk()
    {
        return $this->hasOne(Sets::className(), ['sets_id_pk' => 'sets_id_fk']);
    }
}

I was also thinking maybe I could put in a hasOne() relation for the specific attribute 'intensity' in 'Sets'

Answer

soju picture soju · Dec 3, 2014

You should simply try this :

<?= $form->field($model->setsintensity, 'intensity') ?>

EDIT : And because "every Set may have one SetsIntensity", you should check this relation before displaying form, e.g. :

if ($model->setsintensity===null)
{
    $setsintensity = new SetsIntensity;
    $model->link('setsintensity', setsintensity);
}

PS: link method requires that the primary key value is not null.