Ok, here is my solution:
Create 2 more clases extended of "Model". So I have 3 clases: Room (ActiveRecord), RoomB (Model), RoomC (Model). So I can representate the 3 types of room.
The attributes of the two "Model" clases, are the "id" and the "description" of the "ActiveRecord" class (remember, we are talking about Room).
In the “_form.php”, I’ve put two “render(’_form-rooms’)” more, inside divs with class “col-md-4” to get the separation.
<td>
<div class="row">
<div class="col-md-4">
<?= $this->render('_form-rooms', [
'form' => $form,
'indexHouse' => $indexHouse,
'modelsRoom' => $modelsRoom[$indexHouse],
]) ?>
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
<div class="col-md-4">
<?= $this->render('_form-rooms', [
'form' => $form,
'indexHouse' => $indexHouse,
'modelsRoom' => $modelsRoomB[$indexHouse],
]) ?>
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
<div class="col-md-4">
<?= $this->render('_form-rooms', [
'form' => $form,
'indexHouse' => $indexHouse,
'modelsRoom' => $modelsRoomC[$indexHouse],
]) ?>
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="fa fa-minus"></span></button>
</div>
</div>
</td>
In the “actionCreate”, I’ve made 2 extra arrays representing the 2 “Model” clases, so I have those 3 arrays: $modelsRoom = [[new Room]]; $modelsRoomB = [[new RoomB]]; $modelsRoomC = [[new RoomC]];
I’ve changed all the logic of the code inside “actionCreate” ad hoc with the two extra arrays, so, for example, in the “isset($_POST[‘Room’][0][0])”, I’ve asking for “isset($_POST[‘RoomB’][0][0])” and “isset($_POST[‘RoomC’][0][0])” as well:
// validate person and houses models
$valid = $modelPerson->validate();
$valid = Model::validateMultiple($modelsHouse) && $valid;
$valid2 = $valid3 = $valid;
if (isset($_POST['Room'][0][0])) {
foreach ($_POST['Room'] as $indexHouse => $rooms) {
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = new Room;
$modelRoom->load($data);
$modelsRoom[$indexHouse][$indexRoom] = $modelRoom;
$valid = $modelRoom->validate();
}
}
}
if (isset($_POST['RoomB'][0][0])) {
foreach ($_POST['RoomB'] as $indexHouse => $rooms) {
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = new Room;
$modelRoom->load($data);
$modelsRoomB[$indexHouse][$indexRoom] = $modelRoom;
$valid2 = $modelRoom->validate();
}
}
}
if (isset($_POST['RoomC'][0][0])) {
foreach ($_POST['RoomC'] as $indexHouse => $rooms) {
foreach ($rooms as $indexRoom => $room) {
$data['Room'] = $room;
$modelRoom = new Room;
$modelRoom->load($data);
$modelsRoomC[$indexHouse][$indexRoom] = $modelRoom;
$valid3 = $modelRoom->validate();
}
}
}
so I ask if the 2 extra "valid" variables are true to continue
if ($valid && $valid2 && $valid3) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelPerson->save(false)) {
foreach ($modelsHouse as $indexHouse => $modelHouse) {
if ($flag === false) {
break;
}
... (continue with the same code)
and, in the render of the form, I’ve pass as a parameter the extra arrays created:
return $this->render('create', [
'modelPerson' => $modelPerson,
'modelsHouse' => (empty($modelsHouse)) ? [new House] : $modelsHouse,
'modelsRoom' => (empty($modelsRoom)) ? [[new Room]] : $modelsRoom,
'modelsRoomB' => (empty($modelsRoomB)) ? [[new RoomB]] : $modelsRoomB,
'modelsRoomC' => (empty($modelsRoomC)) ? [[new RoomC]] : $modelsRoomC,
]);
In the “_form.php” view, you can see the code above, I’ve used the two extra arrays in the render of the two extra “_form-rooms”.
In the “_form-rooms”, I’ve removed the code representing the model’s id, because in the “actionUpdate”, I’ve remove all the “Houses”, so, all their “rooms” will be deleted too. After this, I’ve just do the same as in the “actionCreate” (after the post).
I hope you can understand my solution. It maybe not the best solution, but it works for me. There are more details that I’ve omited to not to extend too much this reply, but you can always contact me
If you need more details, email me.