लारवेल - एलोक्जेंट "है", "विथ", "व्हेयरहास" - उनका क्या मतलब है?


211

मैं अवधारणा मिल गया है और इन तरीकों के पीछे अर्थ एक छोटे से भ्रमित होने की है, यह किसी को मुझे समझा के लिए संभव है क्या बीच का अंतर hasऔर withएक उदाहरण के संदर्भ (यदि संभव हो) में, है?

जवाबों:


555

साथ में

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

उदाहरण:

User > hasMany > Post

$users = User::with('posts')->get();
foreach($users as $user){
    $users->posts; // posts is already loaded and no additional DB query is run
}

है

has()एक रिश्ते के आधार पर चयन मॉडल को फ़िल्टर करना है। तो यह सामान्य WHERE की स्थिति के समान ही कार्य करता है। यदि आप has('relation')इसका उपयोग करते हैं तो इसका मतलब है कि आप केवल उन मॉडल को प्राप्त करना चाहते हैं जिनके पास इस संबंध में कम से कम एक संबंधित मॉडल है।

उदाहरण:

User > hasMany > Post

$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection

कहां है

whereHas()मूल रूप से समान काम करता है, has()लेकिन आपको संबंधित मॉडल की जांच के लिए अतिरिक्त फिल्टर निर्दिष्ट करने की अनुमति देता है।

उदाहरण:

User > hasMany > Post

$users = User::whereHas('posts', function($q){
    $q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned

101
+1, बहुत उपयोगी उत्तर! यह भी ध्यान दें कि जहां with('relation')संबंधित तालिका का डेटा लौटा संग्रह में शामिल होगा , has('relation')और संबंधित तालिका के डेटा को शामिल नहींwhereHas('relation') करेगा । तुम दोनों कॉल करने के लिए आवश्यकता हो सकती है तो साथ ही साथ या । with('relation')has()whereHas()
सोलिस्टर

1
अभिवादन उत्तर, उदाहरण के लिए रिलेशनशिप मॉडल से पेरेंट मॉडल का उपयोग कैसे करें, यूजर मॉडल की विशेषताओं के आधार पर पोस्ट मॉडल कैसे खोजें
hussainfrotan

@BhojendraNepal दुर्भाग्य से डॉक्स में इसके बारे में बहुत कुछ प्रतीत नहीं होता है ... यह सब मुझे मिला (यह कुछ पैराग्राफ नीचे है)
ल्यूकसैजिटर

@hussainfrotan उसी तरह, whereHasजब पोस्ट को क्वेरी करते समय उपयोगकर्ता संबंध पर उपयोग करें।
माइकल त्सांग

जिज्ञासु, लारवेल डॉक्यूमेंटेशन में: laravel.com/docs/5.8/eloquent-relationships , जब whereHasइसका उपयोग करता है use Illuminate\Database\Eloquent\Builder;जो तब साथ होता है function(Builder $query)। ज्यादातर उदाहरण जो मैंने देखे, डॉट का उपयोग करते हैं Builder, बस $ क्वेरी में पास होते हैं, जो सही तरीका है?
गुंटर

8

दस्तावेज़ पहले ही उपयोग की व्याख्या कर चुका है। इसलिए मैं इन तरीकों को समझाने के लिए SQL का उपयोग कर रहा हूं

उदाहरण:


मान लिया गया है Order (orders)कि कई हैं OrderItem (order_items)

और आप पहले से ही उनके बीच संबंध बना चुके हैं।

// App\Models\Order:
public function orderItems() {
    return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}

ये तीन विधियां एक रिश्ते पर आधारित हैं ।

साथ में


परिणाम: with() मॉडल ऑब्जेक्ट और उसके संबंधित परिणाम लौटाएं।

लाभ: यह उत्सुक-लोडिंग है जो एन + 1 समस्या को रोक सकता है

जब आप निम्नलिखित विशिष्ट बिल्डर का उपयोग कर रहे हैं:

Order::with('orderItems')->get();

Laravel ने इस कोड को केवल दो SQL में बदला :

// get all orders:
SELECT * FROM orders; 

// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);

और फिर लार्वा दूसरी एसक्यूएल के परिणामों को विदेशी कुंजी द्वारा पहली एसक्यूएल के परिणामों से अलग मर्ज करते हैं । अंत में संग्रह के परिणाम लौटाएँ।

इसलिए यदि आपने क्लोज़र में विदेशी_की के बिना कॉलम चुना है, तो रिलेशनशिप रिजल्ट खाली होगा:

Order::with(['orderItems' => function($query) { 
           // $query->sum('quantity');
           $query->select('quantity'); // without `order_id`
       }
])->get();

#=> result:
[{  id: 1,
    code: '00001',
    orderItems: [],    // <== is empty
  },{
    id: 2,
    code: '00002',
    orderItems: [],    // <== is empty
  }...
}]

है


Hasमॉडल का ऑब्जेक्ट वापस कर देगा कि उसका संबंध खाली नहीं है

Order::has('orderItems')->get();

Laravel ने इस कोड को एक SQL में बदला :

select * from `orders` where exists (
    select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)

कहां है


whereHasऔर आपके प्रश्नों पर शर्तें orWhereHasलगाने के तरीके । ये विधियां आपको एक रिश्ते की बाधा के लिए अनुकूलित बाधाओं को जोड़ने की अनुमति देती हैं ।wherehas

Order::whereHas('orderItems', function($query) {
   $query->where('status', 1);
})->get();

Laravel ने इस कोड को एक SQL में बदला :

select * from `orders` where exists (
    select * 
    from `order_items` 
    where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.