लारवेल एलोकेंट में "के साथ ()" फ़ंक्शन का उपयोग करके विशिष्ट कॉलम प्राप्त करें


197

मेरे पास दो टेबल हैं, Userऔर Post। एक Userकई हो सकते हैं postsऔर एक postकेवल एक का है user

मेरे Userमॉडल में मेरा hasManyरिश्ता है ...

public function post(){
    return $this->hasmany('post');
}

और मेरे postमॉडल में मेरा belongsToरिश्ता है ...

public function user(){
    return $this->belongsTo('user');
}

अब मैं इन दो तालिकाओं का उपयोग Eloquent with()करना चाहता हूं, लेकिन दूसरी तालिका से विशिष्ट कॉलम चाहते हैं। मुझे पता है कि मैं क्वेरी बिल्डर का उपयोग कर सकता हूं लेकिन मैं नहीं करना चाहता।

जब Postमॉडल में मैं लिखता हूं ...

public function getAllPosts() {
    return Post::with('user')->get();
}

यह निम्नलिखित प्रश्नों को चलाता है ...

select * from `posts`
select * from `users` where `users`.`id` in (<1>, <2>)

लेकिन मैं जो चाहता हूं ...

select * from `posts`
select id,username from `users` where `users`.`id` in (<1>, <2>)

जब मैं उपयोग ...

Post::with('user')->get(array('columns'....));

यह केवल पहली तालिका से कॉलम लौटाता है। मैं with()दूसरी तालिका से विशिष्ट कॉलम का उपयोग करना चाहता हूं । मैं उसे कैसे कर सकता हूँ?

जवाबों:


347

खैर मुझे इसका हल मिल गया। यह एक closureफंक्शन पास करके किया जा सकता है with()जैसे ऐरे के दूसरे इंडेक्स में

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();

यह केवल का चयन करेंगे idऔर usernameअन्य मेज से। मुझे उम्मीद है कि इससे दूसरों को मदद मिलेगी।


याद रखें कि प्राथमिक कुंजी (इस मामले में आईडी) को $ क्वेरी में पहला परम होने की आवश्यकता है-> चयन () वास्तव में आवश्यक परिणाम प्राप्त करने के लिए। *।


1
यह अजीब है, मुझे यह काम करने के लिए नहीं मिला। जैसे ही मैंने इसमें जोड़ा $query->select('id','username');, मैं हो रहा थाTrying to get property of non-object
user1669496

5
अजीब! अभी भी उपयोगकर्ता के सभी क्षेत्रों को लौटाता है। @AwaisQarni
जस्टिन

2
इसे साझा करने के लिए आपको धन्यवाद। आपको यह संभावना कहां से मिली? मुझे यह Laravel डॉक्स में नहीं मिला।
साइमन टिम्मरमन्स

81
इसे देखने वालों के लिए, याद रखें कि प्राथमिक कुंजी ( idइस मामले में) $query->select()वास्तव में आवश्यक परिणाम प्राप्त करने के लिए आवश्यक है। मैंने अपने कोड में इसे छोड़ दिया और यह पता नहीं लगा सका कि यह कोई परिणाम क्यों नहीं मिलेगा। मुझे मूर्ख! आशा है कि यह किसी और को भी इसी समस्या के साथ मदद करता है
Azirius

4
बहुत बढ़िया, बस विदेशी कुंजी जोड़ने की जरूरत है, यहाँ पर इसके post_id अन्यथा परिणाम खाली हो जाएगा। विदेशी कुंजी का उल्लेख करना यहाँ महत्वपूर्ण है। धन्यवाद :)
हशम अहमद

102

आप इसे Laravel 5.5 के बाद से कर सकते हैं:

Post::with('user:id,username')->get();

idक्षेत्र के लिए देखभाल और डॉक्सforeign keys में कहा गया है :

इस सुविधा का उपयोग करते समय, आपको हमेशा अपने द्वारा पुनः प्राप्त करने की इच्छा वाले कॉलम की सूची में आईडी कॉलम और किसी भी प्रासंगिक विदेशी कुंजी कॉलम को शामिल करना चाहिए।

उदाहरण के लिए, यदि उपयोगकर्ता किसी टीम का है और उसके पास team_idएक विदेशी कुंजी कॉलम है, तो $post->user->teamयदि आप निर्दिष्ट नहीं करते हैं तो खाली है team_id

Post::with('user:id,username,team_id')->get();

13
रिश्ते को सुलझाने के लिए विदेशी कुंजी (यहां यह पोस्ट_ड मानकर) शामिल करना न भूलें, अन्यथा आपको अपने रिश्ते के लिए खाली परिणाम मिलेंगे।
हशाम अहमद

2
यह वास्तव में चयनित उत्तर होना चाहिए। एक आकर्षण की तरह काम करता है :)
ग्राहम

@ एडम, यह चाइल्ड टेबल में कॉलम को प्रतिबंधित करेगा, मैं टेबल के साथ टेबल को पेरेंट टेबल से चाइल्ड टेबल पर कैसे रोक सकता हूं?
सोडियम

@GauravGenius सब कुछ आप get()विधि में मान्यता से प्रतिबंधित करना चाहते हैंPost::with('user:id,username')->get(['age', 'color']);
एडम

82

अपने Postमॉडल में

public function user()
{
    return $this->belongsTo('User')->select(array('id', 'username'));
}

मूल क्रेडिट लारवेल ईगर लोडिंग में जाता है - केवल विशिष्ट कॉलम लोड करें


14
लेकिन यह रिश्ता इसे हार्डकोड की तरह बना देगा। हर हालत में यह मुझे हमेशा इन दोनों क्षेत्रों में लौटाएगा। ऐसा हो सकता है कि मुझे कुछ अन्य स्थितियों में अधिक क्षेत्रों की आवश्यकता हो
Awais Qarni

फिर आपको क्वेरी बिल्डर का उपयोग करना होगा।
user1669496

5
यह स्वीकृत उत्तर होना चाहिए। यह करने का सही तरीका है।
बगुनटरुके

1
क्या लारवेल 5.3 संस्करण में ऐसा करने का कोई तरीका है? मुझे लगता है कि उन्होंने इसे बदल दिया ... फिर से .... और अब यह शून्य हो जाता है जब मैं इस दृष्टिकोण के साथ कोशिश करता हूं
आंद्रे एफ।

यह एक समय हो गया है, लेकिन आप एक $fieldsपैरामीटर जोड़ सकते हैं ।
जोर्डेव

69

दूसरे रास्ते से जाते समय (हैमनी):

User::with(array('post'=>function($query){
    $query->select('id','user_id');
}))->get();

संबंध को हल करने के लिए विदेशी कुंजी को शामिल करना न भूलें (यह इस उदाहरण में user_id है), अन्यथा आप अपने संबंध के लिए शून्य परिणाम प्राप्त करेंगे।


6
हां, वास्तव में, "विदेशी कुंजी को शामिल करना न भूलें (यह इस उदाहरण में user_id है)"
aqingsao

आपको ऐसे स्तंभों को शामिल करना चाहिए जो आपके संबंधों को चुनिंदा क्षेत्रों में परिभाषित करते हैं, इस मामले में user_id
alimfazeli

अच्छा पकड़ा भाई।
शाहरुख अनवर

भयानक भाई, विदेशी कुंजी का उपयोग करना वास्तव में महत्वपूर्ण है, भाग्यशाली है कि मैंने आपका ans देखा अन्यथा मैंने घंटों तक अपना सिर खरोंच कर दिया। धन्यवाद दोस्त!
हशाम अहमद

34

Laravel 5.7 में आप इस तरह के विशिष्ट क्षेत्र को कॉल कर सकते हैं

$users = App\Book::with('author:id,name')->get();

foreign_keyचयन में क्षेत्र जोड़ना महत्वपूर्ण है ।


11
विदेशी कुंजी क्षेत्र को जोड़ने के लिए मत भूलना
hend1

2
@ Hendra1 की टिप्पणी को नोटिस करना न भूलें, प्राथमिक कुंजी के साथ-साथ सभी विदेशी कुंजी फ़ील्ड भी आवश्यक हैं, अन्यथा आपको रिक्त संग्रह मिलेगा। यार मेरा समय बच गया। धन्यवाद
राजेश Vishnani

14

आपके Postमॉडल में:

public function userWithName()
{
    return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}

अब आप उपयोग कर सकते हैं $post->userWithName


2
वास्तव में? मेरे लिए यह सिर्फ कुछ भी नहीं लौटाता है, अर्थात इसे तोड़ता है?
Sjwdavies

12

यदि आप with()लार्वा लूप में उपयोग करके विशिष्ट कॉलम प्राप्त करना चाहते हैं, तो आप नीचे दिए गए कोड का उपयोग कर सकते हैं, जो मूल रूप से इस प्रश्न के उत्तर में @Adam द्वारा उनके उत्तर में दिया गया है:

Post::with('user:id,username')->get();

इसलिए मैंने इसे अपने कोड में उपयोग किया है लेकिन यह मुझे त्रुटि दे रहा है 1052: Column 'id' in field list is ambiguous, इसलिए यदि आप लोग भी उसी समस्या का सामना कर रहे हैं

फिर इसे हल करने के लिए आपको with()नीचे कोड के रूप में आईडी कॉलम से पहले तालिका का नाम निर्दिष्ट करना होगा :

Post::with('user:user.id,username')->get();

यह मेरे लिए शून्य है, लेकिन मुझे नहीं पता था कि यह पहले संभव था! ठीक है, तो मैंने प्रीमैटरली पोस्ट किया लेकिन मुझे इसका परिणाम नहीं मिला। इस विधि का उपयोग करने के लिए (बहुत क्लीनर दिखता है) आपको संबंध लिंक शामिल करना चाहिए, उदाहरण के लिए डेटा के साथ खींचते समय आईडी कॉलम। इस विनिर्देशक के बिना, आपको एक शून्य रिटर्न मिलता है।
Adsy2010

हाँ @ Adsy2010, संबंधित संबंध डेटा प्राप्त करने के लिए आपको आईडी कॉलम या प्राथमिक कुंजी या जो भी आईडी है, उस संबंध के लिए जिम्मेदार होना चाहिए।
हरितसिंह गोहिल

10

मैं इस मुद्दे पर आया था लेकिन संबंधित वस्तुओं की एक दूसरी परत के साथ। @Awais Qarni का उत्तर नेस्टेड चयन कथन में उपयुक्त विदेशी कुंजी को शामिल करने के साथ है। जिस तरह संबंधित मॉडल को संदर्भित करने के लिए पहले नेस्टेड चयन कथन में एक आईडी की आवश्यकता होती है, उसी तरह संबंधित मॉडल की दूसरी डिग्री के संदर्भ में विदेशी कुंजी की आवश्यकता होती है; इस उदाहरण में कंपनी मॉडल।

Post::with(['user' => function ($query) {
        $query->select('id','company_id', 'username');
    }, 'user.company' => function ($query) {
        $query->select('id', 'name');
    }])->get();

इसके अतिरिक्त, यदि आप पोस्ट मॉडल से विशिष्ट स्तंभों का चयन करना चाहते हैं, तो आपको इसे संदर्भित करने के लिए चयन कथन में user_id कॉलम को शामिल करना होगा।

Post::with(['user' => function ($query) {
        $query->select('id', 'username');
    }])
    ->select('title', 'content', 'user_id')
    ->get();

4

ध्यान दें कि यदि आपको केवल तालिका से एक कॉलम की आवश्यकता है तो 'सूचियों' का उपयोग करना काफी अच्छा है। मेरे मामले में मैं एक उपयोगकर्ता के पसंदीदा लेखों को पुनः प्राप्त कर रहा हूं लेकिन मैं केवल लेख आईडी चाहता हूं:

$favourites = $user->favourites->lists('id');

आईडी की एक सरणी लौटाता है, उदाहरण के लिए:

Array
(
    [0] => 3
    [1] => 7
    [2] => 8
)

यह एक संग्रह वापस!
गियोवन्नी सुदूर

यदि आप एक सरणी चाहते हैं तो कॉल करें toArray()!!! $user->favourites->lists('id')->toArray();
गियोवन्नी सुदूर

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

-1 चयनित सभी क्षेत्रों के साथ $user->favouritesवापस आ जाएगा Collection। सही उपयोग है: $user->favourites()->lists('id')
वालेस मैक्सर्स

बाद में PHP फ़िल्टरिंग का उपयोग करने के लिए सब कुछ का चयन करना एक बुरा विचार है। क्वेरी में केवल आवश्यक फ़ील्ड का उपयोग करना सबसे अच्छा है। Query\Builder::listsविधि और Collection::listsविधि के बीच अंतर जानना महत्वपूर्ण है ।
वालेस मैक्सर्स

1

आप इसे एक्सेस करने के समय संबंधित मॉडल पर कॉलम भी निर्दिष्ट कर सकते हैं।

Post::first()->user()->get(['columns....']);


0

अब आप pluckएक Collectionउदाहरण पर विधि का उपयोग कर सकते हैं :

यह केवल की uuidविशेषता लौटाएगाPost model

App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
     all: [
       "1",
       "2",
       "3",
     ],
   }


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