दो स्पष्ट संग्रह को कैसे मिलाएं?


86

मेरे पास एक प्रश्न तालिका और एक टैग तालिका है। मैं दिए गए प्रश्न के टैग से सभी प्रश्नों को लाना चाहता हूं। इसलिए, उदाहरण के लिए, मेरे पास "यात्रा", "ट्रेनें" और "संस्कृति" टैग हो सकते हैं जो किसी दिए गए प्रश्न से जुड़े हैं। मैं उन तीन टैगों के लिए सभी प्रश्नों को लाने में सक्षम होना चाहता हूं। मुश्किल, इसलिए ऐसा लगता है, कि प्रश्न और टैग संबंध एक बहुत-से-बहुत-से परिभाषित है, जो किTTMMany के रूप में एलोकेंट में परिभाषित किया गया है।

मैंने प्रश्नों को नीचे के रूप में एकत्र करने का प्रयास करने के बारे में सोचा:

foreach ($question->tags as $tag) {
    if (!isset($related)) {
        $related = $tag->questions;
    } else {
        $related->merge($tag->questions);
    }
}

हालांकि यह काम करने के लिए प्रतीत नहीं होता है। कुछ भी विलय नहीं लगता है। क्या मैं इसे सही ढंग से करने का प्रयास कर रहा हूं? इसके अलावा, एलोकेंट में कई-से-कई संबंधों में पंक्तियों की एक पंक्ति लाने का एक बेहतर तरीका है?


क्या आपने उत्सुक लोडिंग और विधि के साथ प्रलेखन की जांच की? आपकी समस्या को बेहतर ढंग से स्पष्ट क्वेरी का उपयोग करके आसानी से हल किया जा सकता है। एक बार जब मैं एक कंप्यूटर के पीछे पड़ जाता हूं तो मैं एक उदाहरण लिखूंगा जब तक कि कोई मुझे इसके लिए नहीं हराता।
लॉजोस

1
@ Luceos withमदद नहीं करेगा। इसकी whereHasआवश्यकता है - नीचे दिए गए उत्तर की तरह।
जारेक टाकज़ीक

हां, मेरी गलती; आप सही हैं
लूसोस

जवाबों:


135

मर्ज विधि मर्ज किए गए संग्रह को लौटाता है, यह मूल संग्रह को म्यूट नहीं करता है, इस प्रकार आपको निम्न कार्य करने की आवश्यकता है

$original = new Collection(['foo']);

$latest = new Collection(['bar']);

$merged = $original->merge($latest); // Contains foo and bar.

अपने कोड में उदाहरण लागू करना

$related = new Collection();

foreach ($question->tags as $tag)
{
    $related = $related->merge($tag->questions);
}

1
मैं एक पेड़ से एक फ्लैट सूची का निर्माण करने की कोशिश कर रहा था, पुश का उपयोग मुझे क्या चाहिए था, लेकिन फॉर्च्यून दृष्टिकोण ने वास्तव में मदद की।
जॉर्ज

ध्यान रखें कि एलोकेंट कलेक्शन सामान्य कलेक्शन की तरह व्यवहार नहीं करते हैं, अर्थात। वे getKeyपरिणामों को मर्ज करने के लिए उपयोग करते हैं , इसलिएModel::all()->merge(Model::all())->count() === Model::all()->count()
eithed

33

merge()पर विधि Collectionसंग्रह जिस पर यह कहा जाता था संशोधित नहीं करता है। इसमें विलय किए गए नए डेटा के साथ एक नया संग्रह देता है। आपको इसकी आवश्यकता होगी:

$related = $related->merge($tag->questions);

हालांकि, मुझे लगता है कि आप गलत कोण से समस्या से निपट रहे हैं।

चूंकि आप ऐसे प्रश्नों की तलाश में हैं, जो एक निश्चित मापदंड को पूरा करते हैं, इसलिए उस तरीके से क्वेरी करना संभव होगा। has()और whereHas()तरीकों एक संबंधित रिकॉर्ड के अस्तित्व के आधार पर एक प्रश्न उत्पन्न करने के लिए उपयोग किया जाता है।

यदि आप ऐसे प्रश्नों की तलाश में थे, जिनमें कोई टैग हो, तो आप has()विधि का उपयोग करेंगे । चूंकि आप एक विशिष्ट टैग के साथ प्रश्नों की तलाश कर रहे हैं, आप whereHas()शर्त जोड़ने के लिए उपयोग करेंगे ।

इसलिए, यदि आप उन सभी प्रश्नों को चाहते हैं जिनमें 'यात्रा', 'रेलगाड़ी', या 'संस्कृति' के साथ कम से कम एक टैग है, तो आपकी क्वेरी इस तरह दिखाई देगी:

$questions = Question::whereHas('tags', function($q) {
    $q->whereIn('name', ['Travel', 'Trains', 'Culture']);
})->get();

यदि आप उन सभी प्रश्नों को चाहते थे जिनमें उन सभी तीन टैग थे, तो आपकी क्वेरी इस तरह दिखाई देगी:

$questions = Question::whereHas('tags', function($q) {
    $q->where('name', 'Travel');
})->whereHas('tags', function($q) {
    $q->where('name', 'Trains');
})->whereHas('tags', function($q) {
    $q->where('name', 'Culture');
})->get();

1
+, हालाँकि आपके द्वारा सुझाए गए 2 वें (सभी टैग) विकल्प को सरल बनाया जा सकता है: stackoverflow.com/a/24706347/784588
Jarek Tkaczyk

लेकिन आप टैग नामों को हार्डकोड नहीं कर सकते। इस उदाहरण में, सवाल उन टैगों का होना होता है, लेकिन अन्य प्रश्नों में टैग अलग
अल्फारिद मोरालेस गार्सिया

24
$users = User::all();
$associates = Associate::all();

$userAndAssociate = $users->merge($associates);

6
इसे पढ़ें (ओवरराइटिंग): medium.com/@tadaspaplauskas/…
Jeffz

1
@ जेफ यह वास्तव में अविश्वसनीय है कि यह अकेले आईडी पर आधारित "डुप्लिकेट" का विलय करता है
andrewtweber

11

एक में दो अलग-अलग वाक्पटु संग्रहों को मिलाएं और कुछ वस्तुओं का एक ही आईडी होना, एक दूसरे को अधिलेखित कर देगा। इसके बजाय पुश () पद्धति का उपयोग करें या उस समस्या से बचने के लिए अपने दृष्टिकोण पर पुनर्विचार करें। वेब का संदर्भ लें


धन्यवाद, इसने मुझे यहां मिली टिप्पणी पर डाल दिया माध्यम @@Jffparr_57441/… जो कि ओवरराइटिंग के बिना सफाई से काम करने के लिए लगता है।
मार्क

1

सभी मेरे लिए शानदार संग्रह पर काम नहीं करते हैं , लार्वा एलोक्वेंट संग्रह उन वस्तुओं से कुंजी का उपयोग करता है जो मुझे लगता है कि विलय के मुद्दों का कारण बनता है, आपको पहले संग्रह को एक सरणी के रूप में वापस लाने की आवश्यकता है, जिसे एक नए संग्रह में डाल दिया जाए और फिर दूसरों को धकेल दें। नया संग्रह;

public function getFixturesAttribute()
{
    $fixtures = collect( $this->homeFixtures->all() );
    $this->awayFixtures->each( function( $fixture ) use ( $fixtures ) {
        $fixtures->push( $fixture );
    });
    return $fixtures;
}

0

प्रत्येक एलोकेंट संग्रह के लिए एक नया आधार संग्रह बनाना मेरे लिए मर्ज का काम करता है।

$foo = collect(Foo::all());
$bar = collect(Bar::all());
$merged = $foo->merge($bar);

इस मामले में इसकी प्राथमिक कुंजियों में कोई गड़बड़ नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.