Yii2: Как проверить отношения? - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть модель с отношением "обзоры":

class ReportStructure extends \yii\db\ActiveRecord
{

    const REVIEW_LIST_NAME = 'reviews';

    public function getReviewList()
    {
        return $this->hasOne(FileIndexList::className(), ['id_owner' => 'id_report'])
            ->where('list_name = :list_name', [':list_name' => self::REVIEW_LIST_NAME]);
    }

    public function getReviews()
    {
        return $this->hasMany(FileIndex::className(), ['id_file_index' => 'id_file_index'])->via('reviewList');
    }
}

Во View отображаются обзоры с помощью виджета GridView.Пользователь может добавлять или удалять отзывы другим представлением.Пользователь должен указать хотя бы один отзыв.Я добавил в модель правило проверки:

public function rules()
{
    return [
        ['reviews', 'checkReviews'],
    ];
}

public function checkReviews($attribute)
{
    if (count($this->reviews) === 0) {
        $this->addError($attribute, 'You should add at least one review');
    }
}

Но, похоже, это правило даже не сработало.

public function actionIndex($idSupply, $restoreTab = false) {

    $this->initData($idSupply, $report, $reestrData, $structure, $elements);

    $ok = $report->load(Yii::$app->request->post()) &&
            $reestrData->load(Yii::$app->request->post()) &&
            Model::loadMultiple($elements, Yii::$app->request->post());

    if($ok) {
        $ok = $report->validate() &&
                $reestrData->validate() &&
                Model::validateMultiple($elements) &&
                $structure->validate();

        if($ok) {
            $report->id_status = Status::STATUS_VERIFIED;
            $this->saveData($report, $reestrData, $structure, $elements);
            return $this->redirect(['supplies/update', 'id' => $idSupply]);
        }
    }
    return $this->render('index', [
                'structure' => $structure,
                'report' => $report,
                'reestrData' => $reestrData,
                'elements' => $elements,
                'restoreTab' => $restoreTab
    ]);
}

Так инициализируются данные.$ elements - это объекты одного класса, я использую для них табличный ввод.

private function initData($idSupply, &$report, &$reestrData, &$structure, &$elements) {
        $report = \app\models\Reports::findOne($idSupply);
        $reestrData = \app\models\ReestrData::findOne($report->id_reestr_data);
        $structure = \app\models\report\ReportStructure::findOne($report->id_supply);

        $elements = [
            'titleIndex' => FileIndex::getInstance($structure->id_title_index, $structure->getAttributeLabel('id_title_index')),
            'abstractIndex' => FileIndex::getInstance($structure->id_abstract_index, $structure->getAttributeLabel('id_abstract_index')),
            'technicalSpecificationIndex' => FileIndex::getInstance($structure->id_technical_specification_index, $structure->getAttributeLabel('id_technical_specification_index')),
            'contentsIndex' => FileIndex::getInstance($structure->id_contents_index, $structure->getAttributeLabel('id_contents_index')),
            'imageListIndex' => FileIndex::getInstance($structure->id_image_list_index, $structure->getAttributeLabel('id_image_list_index'), false),
            'tableListIndex' => FileIndex::getInstance($structure->id_table_list_index, $structure->getAttributeLabel('id_table_list_index'), false),
            'textAnnexListIndex' => FileIndex::getInstance($structure->id_text_annex_list_index, $structure->getAttributeLabel('id_text_annex_list_index'), false),
            'graphAnnexListIndex' => FileIndex::getInstance($structure->id_graph_annex_list_index, $structure->getAttributeLabel('id_graph_annex_list_index'), false),
            'glossaryIndex' => FileIndex::getInstance($structure->id_glossary_index, $structure->getAttributeLabel('id_glossary_index'), false),
            'reportIntroductionIndex' => FileIndex::getInstance($structure->id_report_introduction_index, $structure->getAttributeLabel('id_report_introduction_index')),
            'reportMainPartIndex' => FileIndex::getInstance($structure->id_report_main_part_index, $structure->getAttributeLabel('id_report_main_part_index')),
            'reportConclusionIndex' => FileIndex::getInstance($structure->id_report_conclusion_index, $structure->getAttributeLabel('id_report_conclusion_index')),
            'bibliographyIndex' => FileIndex::getInstance($structure->id_bibliography_index, $structure->getAttributeLabel('id_bibliography_index')),
            'metrologicalExpertiseIndex' => FileIndex::getInstance($structure->id_metrologicalexpertise_index, $structure->getAttributeLabel('id_metrologicalexpertise_index')),
            'patentResearchIndex' => FileIndex::getInstance($structure->id_patent_research_index, $structure->getAttributeLabel('id_patent_research_index')),
            'costStatementIndex' => FileIndex::getInstance($structure->id_cost_statement_index, $structure->getAttributeLabel('id_cost_statement_index')),
        ];
    }

И вот как данные сохраняются:

private function saveData($report, $reestrData, $structure, $elements) {
        $reestrData->save(false);
        $report->save(false);

        foreach ($elements as $element) {
            $element->save(false);
        }

        $structure->id_title_index = $elements['titleIndex']->id_file_index;
        $structure->id_abstract_index = $elements['abstractIndex']->id_file_index;
        $structure->id_technical_specification_index = $elements['technicalSpecificationIndex']->id_file_index;
        $structure->id_contents_index = $elements['contentsIndex']->id_file_index;
        $structure->id_image_list_index = $elements['imageListIndex']->id_file_index;
        $structure->id_table_list_index = $elements['tableListIndex']->id_file_index;
        $structure->id_text_annex_list_index = $elements['textAnnexListIndex']->id_file_index;
        $structure->id_graph_annex_list_index = $elements['graphAnnexListIndex']->id_file_index;
        $structure->id_glossary_index = $elements['glossaryIndex']->id_file_index;
        $structure->id_report_introduction_index = $elements['reportIntroductionIndex']->id_file_index;
        $structure->id_report_main_part_index = $elements['reportMainPartIndex']->id_file_index;
        $structure->id_report_conclusion_index = $elements['reportConclusionIndex']->id_file_index;
        $structure->id_bibliography_index = $elements['bibliographyIndex']->id_file_index;
        $structure->id_metrologicalexpertise_index = $elements['metrologicalExpertiseIndex']->id_file_index;
        $structure->id_patent_research_index = $elements['patentResearchIndex']->id_file_index;
        $structure->id_cost_statement_index = $elements['costStatementIndex']->id_file_index;

        $structure->save(false);
    }

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Я думаю, что лучше проверить это перед методом удаления.Вы можете добавить этот метод к своей модели и проверить, если это единственный отзыв, а затем возвращает false.

public function beforeDelete()
{
    if (!parent::beforeDelete()) {
        return false;
    }

    if(self::find()->count() >1)
        return true;
    else
        return false;
}
0 голосов
/ 12 сентября 2018

В конце концов я решил вообще не использовать проверку для отношения и просто проверить количество отзывов в контроллере:

if (count($structure->reviews) === 0) {
                $ok = false;
                Yii::$app->session->setFlash('danger', 'You should add at least one review!');

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...