Laravel कई रिश्तों को सहेजता / अपडेट करता है


85

किसी को भी कई रिश्तों को बचाने के लिए मेरी मदद कर सकते हैं? मेरे पास कार्य हैं, उपयोगकर्ता के कई कार्य हो सकते हैं और कार्य में कई उपयोगकर्ता (कई से कई) हो सकते हैं, जो मैं प्राप्त करना चाहता हूं वह यह है कि अपडेट फॉर्म में व्यवस्थापक कई उपयोगकर्ताओं को विशिष्ट कार्य सौंप सकता है। यह HTML कई चुनिंदा इनपुट के माध्यम से किया जाता है

name="taskParticipants[]"

यहां पकड़ यह है कि उसी फॉर्म (इनपुट) के माध्यम से आप उपयोगकर्ताओं को जोड़ / हटा सकते हैं, इसीलिए मुझे सिंक () का उपयोग करना होगा। शायद मुझे शुरू से शुरू करना चाहिए, लेकिन यह नहीं पता कि कहां से शुरू करें ...

यह मेरा उपयोगकर्ता मॉडल है:

public function tasks()
{
    return $this->belongsToMany('Task','user_tasks');
}

टास्क मॉडल

public function taskParticipants()
{
    return $this->belongsToMany('User','user_tasks');
}

TaskController

public function update($task_id)
{
    if (Input::has('taskParticipants'))
    {
        foreach(Input::get('taskParticipants') as $worker)
        {
            $task2 = $task->taskParticipants->toArray();
            $task2 = array_add($task2,$task_id,$worker);
            $task->taskParticipants()->sync(array($task2));
        }
    }
}

यह तालिका कार्य आईडी की संरचना है । शीर्षक | समय सीमा

user_tasks
id|task_id|user_id

मैंने अपना कोड अपडेट कर दिया है। लिंक
SuperManSL

4
$workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers);और जब तक आप कार्य करने के लिए असाइन किए गए सभी उपयोगकर्ताओं को उस प्रपत्र से पास करते हैं, तब तक आपकी आवश्यकता है।
जारेक टकाज़ीक

@JarekTkaczyk धन्यवाद, यह जादुई था।
Ryu_hayabusa

जवाबों:


191

tldr; sync2 परम के साथ प्रयोग करेंfalse


belongsToManyदोनों मॉडल पर कई-कई संबंध हैं:

// Task model
public function users()
{
  return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk
}

// User model
public function tasks()
{
  return $this->belongsToMany('Task', 'user_tasks');
}

नए संबंध उपयोग को जोड़ने के लिए attachया sync

दोनों के बीच अंतर है:

1 attach अगर वह पहले से ही है तो जाँच के बिना धुरी की मेज पर नई पंक्ति जोड़ देगा। उदाहरण के लिए, जब आपके पास अतिरिक्त डेटा जुड़ा हो तो अच्छा है:

Userऔर Examपिवट टेबल के साथ जुड़ा हुआ हैattempts: id, user_id, exam_id, score

मुझे लगता है कि यह आपकी स्थिति में आपकी जरूरत नहीं है:

$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]

$user->tasks()->attach([5,6,7]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]

2 sync दूसरे हाथ पर, या तो सभी संबंधों को हटाने और उन्हें सेट अप नए सिरे से होगा:

$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]

$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]

या यह पिछले और बिना डुप्लिकेट को जोड़े बिना नए संबंधों को स्थापित करेगा:

$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]

8
यह अच्छा होगा यदि वह एपीआई डॉक्स के बजाय मुख्य डॉक्स में प्रलेखित किया गया था! रॉक ऑन। +1।
सिजॉयज

मुझे वास्तव में सिंक और 2 पैरामीटर के साथ दूसरा समाधान पसंद है। जैसा कि मैंने टिप्पणी में कहा था, मैं अलग नहीं कर सकता का उपयोग करें। कहानी यह है कि व्यवस्थापक उपयोगकर्ताओं को कार्य सौंप सकता है। वह ड्रॉपडाउन (एकाधिक) से उपयोगकर्ताओं का चयन करता है, क्षेत्र प्रतिभागियों [] है। तो ...: चरण 1: व्यवस्थापक तीन उपयोगकर्ताओं को कार्य असाइन करता है (आपकी विधि कार्य करती है, हमारे पास DB में 3 रिकॉर्ड हैं) चरण 2: व्यवस्थापक अद्यतन कार्य A और दो उपयोगकर्ता जोड़ता है (आपकी विधि कार्य करती है, हमारे पास DB में 5 रिकॉर्ड हैं) चरण 3: व्यवस्थापक अद्यतन कार्य A और 1 उपयोगकर्ता को निकालता है (आपकी विधि विफल हो जाती है, हमारे पास अभी भी 4 के बजाय 5 उपयोगकर्ता हैं) मेरी अपडेट विधि मेरा कोड
SuperManSL

1
$this->belongsToMany('User')यदि आप तालिका का नाम वर्णानुक्रम और एकवचन (तो task_userइसके बजाय user_tasks) का उपयोग करते हैं तो आप अपने रिश्ते की क्वेरी को सरल बना सकते हैं
Kousha

@ रोकें यदि आप हमेशा सभी संबंधित उपयोगकर्ताओं का एक सरणी पास करते हैं, तो कोचिंग के syncसाथ उपयोग करें , कोई चिंता नहीं। मेरा सुझाव है कि जब भी आप idसंबंधित मॉडल में से किसी एक को पास करते हैं, तो जब भी आप 'किसी उपयोगकर्ता के लिए नया कार्य जोड़ना चाहते हैं' या 'किसी कार्य के लिए उपयोगकर्ता को असाइन करना चाहते हैं' पर सेट 2 पैरा का उपयोग करना चाहिए ।
जारेक टकाज़ीक

1
@FabioAntunes , और सूचियों के syncसाथ एक सरणी देता है । कुछ भी नहीं लौटाता है, लेकिन दोनों ही मामलों में आपको एक अपवाद मिलेगा यदि db कॉल में कुछ अप्रत्याशित ख़ुशी हो। detachedattachedupdatedattach
जारेक टाकज़ीक

106

यहां पर मेरे नोट्स सभी सहेजे गए रिश्तों को सहेजने और अद्यतन करने के बारे में हैं।

में एक करने के लिए एक :

आपको पहले मॉडल पर HasOne और दूसरे मॉडल पर BelongsTo का उपयोग करना होगा

पहले मॉडल पर रिकॉर्ड जोड़ने के लिए ( HasOne ) सेव  फंक्शन का उपयोग करें

उदाहरण:    $post->comments()->save($comment);

दूसरे मॉडल पर रिकॉर्ड जोड़ने के लिए ( BelongsTo ) सहयोगी फ़ंक्शन का उपयोग करें 

उदाहरण:    $user->account()->associate($account);    $user->save();


में कई करने के लिए एक :

आपको पहले मॉडल पर HasMany और दूसरे मॉडल पर BelongsTo का उपयोग करना होगा

पहली तालिका ( HasMany ) पर रिकॉर्ड जोड़ने के लिए सहेजें  या saveMany फ़ंक्शन का उपयोग करें

उदाहरण:    $post->comments()->saveMany($comments);

दूसरे मॉडल पर रिकॉर्ड जोड़ने के लिए ( BelongsTo ) सहयोगी फ़ंक्शन का उपयोग करें 

उदाहरण:    $user->account()->associate($account);    $user->save();


में कई कई को :

आपको पहले मॉडल पर BelongsToMany और दूसरे मॉडल पर BelongsToMany का उपयोग  करना होगा

पिवट टेबल पर रिकॉर्ड जोड़ने के लिए अटैच या सिंक फ़ंक्शंस का उपयोग करें

  • दोनों फ़ंक्शन एकल ID या ID की सरणी को स्वीकार करते हैं 

  • अंतर जाँचता है अगर रिकॉर्ड पहले से ही पिवट टेबल पर मौजूद है जबकि सिंक नहीं है

उदाहरण: $user->roles()->attach($roleId);


में कई के बहुरूपी एक :

आपको मुख्य मॉडल पर मॉर्फमनी और सभी (*** सक्षम) मॉडलों पर  मॉर्फोटो का उपयोग  करना होगा

अन्य सभी मॉडलों में रिकॉर्ड जोड़ने के लिए सेव का उपयोग करें 

उदाहरण:    $course->tags()->save($tag);

पिवट टेबल में निम्नलिखित कॉलम होने चाहिए:

। मुख्य मॉडल आईडी

। (*** सक्षम) आईडी

। (*** सक्षम) प्रकार


में बहुरूपी कई करने के लिए कई :

आपको MorphByMany का उपयोग  मुख्य मॉडल और  MorphToMany के सभी (*** सक्षम) मॉडल पर करना होगा

अन्य सभी मॉडलों में रिकॉर्ड जोड़ने के लिए सेव या सेवमनी का उपयोग करें

उदाहरण:    $course->tags()->save($tag);

उदाहरण:    $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);

पिवट टेबल में निम्नलिखित कॉलम होने चाहिए:

। मुख्य मॉडल आईडी

। (*** सक्षम) आईडी

। (*** सक्षम) प्रकार


के माध्यम से कई में (शॉर्टकट):

आपको पहले टेबल पर HasManyThrough का उपयोग करना होगा और अन्य 2 टेबलों पर सामान्य संबंध बनाने होंगे

यह ManyToMany रिश्तों के लिए काम नहीं करता है (जहां एक पिवट टेबल है)

हालाँकि इसके लिए एक अच्छा और आसान उपाय है।


इस उत्तर से प्रेरित एक लेख मैंने यहां लिखा है। इसे जांचना महत्वपूर्ण है: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209


मैंने वास्तव में इस उत्तर को रखा जब उनके पास पहले से ही सही उत्तर पर 40 से अधिक लाइक थे, लेकिन हां मुझे पता है कि यह मेरे लिए कितना उपयोगी है, आपको यह पसंद है :)
महमूद ज़ाल्ट

1
काश तुम जानते हो कि तुम एक उद्धारकर्ता हो
Chay22

1
यह एक महान जवाब है।
कारो

1
कैसे एक संबंध को अद्यतन करने के लिए कर सकते हैं। u समझाया कि कैसे जोड़ना है। क्या आप कृपया अपडेट भी बता सकते हैं? क्या इस तरह से रिकॉर्ड को अपडेट करने की कोई विधि updateManyहै? धन्यवाद
हमीद्रेज़ा

3

syncWithoutDetaching([$id_one, $id_two, $id_three]);वह है जो आप ढूंढ रहे हैं। वास्तव में यह सटीक काम करता है [ sync2 परम के साथ false] करता है!


0

syncसमारोह बाहर निकलने रिश्तों obliterates और अपने सरणी संबंधों की पूरी सूची बनाता है। आप attachदूसरों को हटाए बिना संबंध जोड़ना चाहते हैं।


मैं अटैचमेंट का उपयोग नहीं कर सकता क्योंकि मैं अपडेट पद्धति के अंदर इस कोड का उपयोग कर रहा हूं। कहानी यह है कि व्यवस्थापक कार्य को अपडेट कर सकता है और इनपुट प्रतिभागियों में भर सकता है [] उन उपयोगकर्ताओं के साथ जो कार्य में भाग लेंगे। इसलिए मुझे यह जांचने की आवश्यकता है कि क्या यह मौजूद है और इसे हटा दें (या नया रिकॉर्ड नहीं जोड़ें) या यदि यह मौजूद नहीं है तो इसे जोड़ दें।
सुपरमैनसेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.