R
R
restyler2014-04-21 10:29:48
Yii
restyler, 2014-04-21 10:29:48

Saving and validating relations in yii2 through forms - how to avoid duplicate attributes in a form?

I have a student (id, name, school_id) model and a school (id, name, ...) model.
It turns out that the school has many students
student always belongs to the same school.

class School extends \yii\db\ActiveRecord
{
/*.....*/
  public function getStudents()
  {
    return $this->hasMany(Student::className(), ['school_id' => 'id']);
  }
/*.....*/
}

When creating a school, I want to display as checkboxes all students to whom the school has not yet been attached, it would seem that it would be logical to do this (in the form template for creating the School model):
<?= $form->field($model, 'students') ->checkboxList(ArrayHelper::map($allStudents, 'id', 'name')) ?>
(there will be few students, so for simplicity we are talking about checkboxes here)
but when I start writing rules to validate the students field (well, for example, to limit the max number of 5 students per school) then the tryin to set readonly attribute exception crashes!
That is, it turns out that relation is a read-only attribute.
How can I beautifully use ActiveForm and validation through the rules of the School model here?
Invent, in addition to students, another field student_ids, which in fact will not exist in the database, but will be used to prescribe rules in the school model?
or is there a "correct" way?
Thank you!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
restyler, 2015-01-11
@restyler

If it is relevant for someone, I solved the issue by introducing an additional attribute selectedStudents for the School class, it is not written to the database, it exists purely for the form and for validation rules.
In the afterSave hook in School we do something like this:

$students = Student::find()->where(['id' => $this->selectedStudents])->all();
foreach ($students as $student) {
   $student->school_id = $this->id; // еще можно использовать метод link()
   $student->save();
}

If you want to avoid such duplicate attributes (students readonly and selectedStudents read / write) at all costs, you need to introduce a separate model for the form so that only the relation remains in the School model, and the selectedStudents attribute already exists in the form model, but it seems to me better to save this for more difficult cases.

I
iopull, 2015-10-28
@iopull

/**
     * @return \yii\db\ActiveQuery
     */
    public function getCategories()
    {
        return $this->hasMany(Category::className(), ['id' => 'category_id'])->viaTable(ProductCategory::tableName(), ['product_id' => 'id']);
    }

    /**
     * @param $value
     */
    public function setCategories($value)
    {
        $this->categories = $value;
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question