2015-11-17 8 views
5

के साथ कई से कई रिश्ते में Yii2 अद्यतन जंक्शन तालिका मेरे पास 3 तालिका है। उदाहरण के लिए, एक आलेख तालिका, एक टैग तालिका, डेटाबेस में एक आलेख_टैग तालिका। लेख और टैग में एन-एम संबंध है।सक्रिय रिकॉर्ड

जब मुझे जंक्शन तालिका में रिश्ते को बचाने के लिए वाईआई 2 के सक्रिय रिकॉर्ड की लिंक() विधि का उपयोग करके नया आलेख जोड़ने की आवश्यकता है, तो यह ठीक काम करता है।

लेकिन जब मुझे जंक्शन तालिका अद्यतन करने की आवश्यकता है। अगर मैं लेख पर लिंक() विधि को दोबारा कॉल करता हूं। यह काम नहीं करेगा। नीचे मेरा कोड और त्रुटि जानकारी है।

$tag_ids = Yii::$app->request->post('Article')['tags']; 
foreach ($tag_ids as $value) { 
    $tag = Tag::findOne($value); 
    $model->link('tags', $tag); 
} 

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '13-1' for key 'PRIMARY' 
The SQL being executed was: INSERT INTO `article_tag` (`article_id`, `tag_id`) VALUES (13, 1) 

क्या मुझे जंक्शन तालिका में सभी डेटा हटाने की आवश्यकता है, फिर इसे अपडेट करने के लिए लिंक() का उपयोग करें ?? या ऐसी सुविधा है जो मैं वाईआई 2 में लापता हूं?

------------------------ अद्यतन --------------------- --------------------

ऐसा लगता है कि मुझे इसे अपने द्वारा शुद्ध एसक्यूएल के साथ करने की आवश्यकता है। मेरे दिमाग को पार करने का सबसे आसान तरीका सबसे पहले जंक्शन तालिका में डेटा हटा देता है, फिर लिंक() का उपयोग पिवट तालिका को फिर से बनाते हैं। यह आसान है लेकिन सूचकांक गड़बड़ कर देगा। इसके अलावा टेबल तेजी से बढ़ता है। ऐसा करने का दूसरा तरीका प्रत्येक रिकॉर्ड को पढ़ना है, फिर इसे रखने या इसे हटाने का फैसला करें। फिर आवश्यक डेटा जोड़ें। इस तरह इसे और अधिक जटिल बनाएं। अधिक कोड की आवश्यकता है।

---------------- फिर से अपडेट करें मैंने एक फ़ंक्शन लिखा ------------------------

public function syncTags($new_tag_ids){ 

    $old_tag_ids = ArrayHelper::getColumn($this->tags, 'id'); 

    $tag_to_delete = array_diff($old_tag_ids, $new_tag_ids); 
    $tag_to_add = array_diff($new_tag_ids, $old_tag_ids); 

    if($tag_to_delete){ 
     //delete tags 
     Yii::$app->db->createCommand() 
      ->delete('article_tag', ['article_id' => $this->id, 'tag_id' => $tag_to_delete]) 
      ->execute(); 
    } 

    if($tag_to_add){ 
     //link new tag assisoated with the article 
     foreach ($tag_to_add as $value) { 
     $tag = Tag::findOne($value); 
     $this->link('tags', $tag); 
     } 
    } 
} 

अब यह woking है, लेकिन नहीं वैश्विक applyable यह मदद मिल सकती है लोगों इसलिए यहाँ पोस्ट लगता है मैं। वाईआई को उस तरह के काम के लिए विस्तार की आवश्यकता है ..

+0

आप कई से अधिक रिश्तों के साथ काम करने के लिए [इस एक्सटेंशन] (https://github.com/arogachev/yii2-many-to-many) को आजमा सकते हैं। – arogachev

+0

या [यह एक] (https://github.com/voskobovich/ManyToManyBehavior)। ऐसा लगता है कि हर किसी ने Yii2 के लिए अपने कई से अधिक एक्सटेंशन लिखे हैं :) – Beowulfenator

+0

मुझे लैरवेल में सिंक() विधि बहुत याद आती है..मुझे बहुत समय बचाओ। – tyan

उत्तर

0

अधिकांश समय मैं केवल इस विधि का उपयोग करता हूं। दूसरा समाधान भी काम कर रहा है, लेकिन मैं पहले को पसंद करता हूं। मैं ऐसे व्यक्ति हूं जो किसी के विस्तार से मदद के बिना समस्या को हल करना पसंद करते हैं।

/** 
* Update categories with the new ones 
* @param array $categories [description] 
* @return null 
*/ 
public function updateCategories($categories = []) 
{ 
    $this->unlinkAll('categories', true); 

    if (! is_array($categories)) 
     return ; 

    foreach ($categories as $category_id) 
    { 
     $category = Category::findOne($category_id); 
     $this->link('categories', $category); 
    } 

    // alternative solution 

    /* 
    $old_categories = $this->getCategories()->asArray()->column(); // get all categories IDs 
    if (! is_array($categories)) 
     $categories = []; 

    $inserted_categories = array_diff($categories, $old_categories); 
    $deleted_categories = array_diff($old_categories, $categories); 

    foreach ($inserted_categories as $category_id) 
    { 
     $category = Category::findOne($category_id); 
     $this->link('categories', $category); 
    } 

    foreach ($deleted_categories as $category_id) 
    { 
     $category = Category::findOne($category_id); 
     $this->unlink('categories', $category, true); 
    } 
    */ 
} 
+0

thks, लेकिन मैं लगभग 2 वर्षों तक php का उपयोग नहीं करता क्योंकि मैं अजगर पर स्विच करता हूं .. – tyan

संबंधित मुद्दे