Задать вопрос

Yii & Yii2. Как вы управляете связанными данными?

Добрый день,
Возник вопрос касательно связанных данных.
Допустим есть таблица со статьями блога. Также есть таблица с тегами. И промежуточная таблица для связи тегов со статьями.
При создании статьи и прикрепления к ней определенных тегов, всё понятно.
Но как правильнее работать с изменениями уже готовой статьи и связей с тегами?
Непосредственно при изменении удалять все связи и прописывать их по заново, в соответствии с выбранными тегами? Либо проверять наличие имеющихся связей, лишние удалять,а новые прописывать?
Как поступаете Вы в такой ситуации?
Спасибо!
  • Вопрос задан
  • 1139 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 3
Ответ в самом низу, но опишу как делаю я, мне может тоже подскажут в комментах.

Обычно это два варианта:
1) Вы не будете использовать релейшены. Тогда просто вытащишь объект и работаешь с ним.
2) Вы будете использовать релейшены. Делай джоин\withJoin

В этом плане доктрина в симфони дружелюбнее, связь содержит инфу, но не содержит объект, т.е что-то типо промежуточного этапа. Как писали выше.

Сейв делаю линком:
$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
$order->link('customer', $customer);

В вышеприведённом примере, метод присвоит атрибуту customer_id объекта Order значение атрибута id объекта Customer и затем сохранит его в базу данных. Тоже самое можно делать и с промежуточными таблицами, линк автоматов вставит строчки в промежуточную таблицу.

При удалении можно использовать метод unlink() - он снимает все связи выставляя Id-шки объектов в null, а если передать с атрибутом $delete = true. Он удалит строку на связи в промежуточной таблице.

Ответ: Да, удалять и заново прописывать.
Ответ написан
Комментировать
sanchezzzhak
@sanchezzzhak
Ля ля ля...
Всегда по разному делаю в основном удаляю добавляю

Но если необходимо удалить/добавить, того что нету, вот способ
protected function saveReferralLinkUser($userModel)
{  
        // получение данных с формы
       $referralLinks = ArrayHelper::getValue(Yii::$app->request->post('ReferralLink', []), 'slug', []);
       // получение текущие данные
        $referralLinkModels = ArrayHelper::map(ReferralLink::findAll(['user_id' => $userModel->id]), 'id', 'slug');
       
       // удаление которых нет в присланных записях
        foreach (array_diff($referralLinkModels, $referralLinks) as $slug) {
            ReferralLink::deleteAll(['slug' => $slug]);
        }
        // добавление тех которых нету в присланных
        foreach (array_diff($referralLinks, $referralLinkModels) as $slug) {
            $referralLink = new ReferralLink(['user_id' => $userModel->id, 'slug' => $slug]);
            $referralLink->save();
        }
}
Ответ написан
Комментировать
@LAV45
https://github.com/LAV45/yii2-target-behavior

Когда-то написал именно для такой же жадачи, но одними тегами этот behavior не ограничивается.
Примеры по использованию можно подсмотреть тут

use lav45\behavior\Target;

/**
 * @property Tag[] $tags
 * @property array $tagValues
 */
class Post extends ActiveRecord
{
    public function rules()
    {
        return [
            [['tagValues'], 'safe'],
        ];
    }

    public function behaviors()
    {
        return [
            [
                'class' => Target::class,
                'targetAttribute' => 'tagValues',
                'targetRelation' => 'tags',
                'delimiter' => ','
            ]
        ];
    }

    public function getTags()
    {
        return $this->hasMany(Tag::className(), ['id' => 'tag_id'])
            ->viaTable('post_tag', ['post_id' => 'id']);
    }
}


$post = new Post();
$post->tagValues = 'foo, bar, baz'; 
$post->tagValues = ['foo', 'bar', 'baz'];
$post->save();
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
R0dger
@R0dger
Laravel/Yii/2 AngularJs PHP RESTful API
Не знаю.. есть похожий функционал... у меня там в транзакции удаляются все связи и устанавливаются новые. Зачем искать разницу, если Вы все равно устанавливаете все связи.. может и есть разница если этих тегов 100 и вы делаете не за одни запрос а за 100.. тогда еще пойму...
Ответ написан
VirmarY
@VirmarY
Full-stack web developer
"проверять наличие имеющихся связей, лишние удалять,а новые прописывать" - вы сами ответили
Ответ написан
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Как поступаете Вы в такой ситуации?

использую Doctrine2 которая хэндлит подобные штуки.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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