Horik_off
@Horik_off
Developer

Правильное сохранение моделей со связанными данными Yii2?

Есть две таблицы
1. Atricles [статьи]
2. Authors [авторы]
3. Articles_Authors [id_статьи id_автора]

Между ними существует связь many to many с id'шниками из первой таблицы и второй.
Какие существуют практики (без сторонних расширений) для сохранения связей в таблице 3.

Как реализовать сохранение данных с учтом того, что данные получаю из XML-файла при парсинге?

На данный момент реализован импорт статей:

foreach ($fileXML->issue->articles->article as $articleFromXML) {
                    $articleForImport = new Articles();
                    $articleForImport->ydk_code = strval($articleFromXML->codes->udk);
                    $articleForImport->header = strval($articleFromXML->artTitles->artTitle);
                    $articleForImport->annotation = strval($articleFromXML->abstracts->abstract);

                    foreach ($articleFromXML->keywords->kwdGroup as $keyWords) {
                        $forImplode = (array)$keyWords->keyword;
                        $keyWordsForImport = implode(', ', $forImplode);
                        $articleForImport->keywords = $keyWordsForImport;
                    }
                    $articleForImport->fk_issue = $issue->id;
                    if ($articleForImport->validate()) {
                        $articleForImport->save();
                    }


И импорт авторов:
foreach ($articleFromXML->authors->author as $authorFromXML) {
                        $authorForImport = new Authors();
                        $authorForImport->surname = (string)$authorFromXML->individInfo->surname;
                        $authorInitials = explode(" ", $authorFromXML->individInfo->initials);
                        $authorForImport->name = $authorInitials[0];
                        $authorForImport->patronymic = $authorInitials[1];
                        $authorForImport->orgName = (string)$authorFromXML->individInfo->orgName;
                        $authorForImport->contactInfo = (string)$authorFromXML->individInfo->email;
                        $authorForImport->additionalInfo = (string)$authorFromXML->individInfo->otherInfo;

                        if ($authorForImport->validate()) {
                            $authorForImport->save();
                        }
                    }


Самое сложное понять как работают модели для сохранения связанных данных в Yii2.
Пытался реализовать что-то наподобие этого (ArticlesAuthors модель, сгенерированная в Gii по таблице ArticlesAuthors по аналогии с таблицами Articles и Authors)
после получения из XML всех авторов и статей пытаюсь создать обьект ArticlesAuthors:

$ArticlesAuthors = new ArticlesAuthors 
 ....
ArticlesAuthors->save();

Все бы хорошо, если бы у каждой статьи был один автор, все бы сработало, но при попытке сохранить статью и авторов вариант выше сохраняте только первого автора первой статьи (хотя у первой статьи авторов три, например).

Как это грамотнее всего реализовывается в Yii2?

И еще. Весь код импорта обернут в транзакцию. Нужно ли использовать, скажем при сохранении только авторов в таблицу Authors метод save() или метод $transaction->commit(); обьявленный после импорта всех данных подразумевает и так сохранение данных?

Спасибо.
  • Вопрос задан
  • 8260 просмотров
Решения вопроса 1
iiifx
@iiifx
PHP, OOP, SOLID, Yii2, Composer, PHPStorm
Самое сложное понять как работают модели для сохранения связанных данных в Yii2.

Просто там все работает. Если вы понимаете, как устроены связи. Существуют: one2one, one2many и many2many. Первые два типа - простые, когда сущность А содержит ссылку на сущность Б. Для организации последнего типа требуется референсная таблица, которая у вас и упоминается, она содержит связи сущностей А и Б.

В вашем варианте, насколько я понял, можно все связи создать вручную:
$article = new Article( [ ... ] );
$article->save();

$author = new Author( [ ... ] );
$author->save();

$article2Author = new ArticleAuthor( [
    'article_id' => $article->id,
    'author_id' => $author->id,
] );
$article2Author->save();
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
gaparchi
@gaparchi
Метод link() можно использовать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы