यह जांचने के लिए कि क्या दिया गया मॉडल दूसरे से संबंधित है, जो आप चाहते हैं यदि मैं आपको सही बताऊं, तो आपको केवल Eloquent
का अधिकतम लाभ उठाने की इस छोटी सी विधि की आवश्यकता है। :
(इसे BaseModel
में लागू करें , Entity
या कोई दायरा, जो भी आपको सूट करे)
// usage
$task->isRelatedTo('transactions.users', $id);
// or
$template->isRelatedTo('tasks.transactions.users', Auth::user());
// or any kind of relation:
// imagine this: User m-m Transaction 1-m Item m-1 Group
$group->isRelatedTo('items.transaction.users', $id);
जादू यहाँ होता है:
/**
* Check if it is related to any given model through dot nested relations
*
* @param string $relations
* @param int|\Illuminate\Database\Eloquent\Model $id
* @return boolean
*/
public function isRelatedTo($relations, $id)
{
$relations = explode('.', $relations);
if ($id instanceof Model)
{
$related = $id;
$id = $related->getKey();
}
else
{
$related = $this->getNestedRelated($relations);
}
// recursive closure
$callback = function ($q) use (&$callback, &$relations, $related, $id)
{
if (count($relations))
{
$q->whereHas(array_shift($relations), $callback);
}
else
{
$q->where($related->getQualifiedKeyName(), $id);
}
};
return (bool) $this->whereHas(array_shift($relations), $callback)->find($this->getKey());
}
protected function getNestedRelated(array $relations)
{
$models = [];
foreach ($relations as $key => $relation)
{
$parent = ($key) ? $models[$key-1] : $this;
$models[] = $parent->{$relation}()->getRelated();
}
return end($models);
}
अरे, लेकिन वहां क्या हो रहा है?
isRelatedTo()
इस तरह काम करता है:
-
जांचें कि क्या पास हुआ
$id
एक मॉडल या सिर्फ एक आईडी है, और$related
. तैयार करता है मॉडल और उसका$id
कॉलबैक में उपयोग के लिए। यदि आप किसी ऑब्जेक्ट को पास नहीं करते हैं तो एलोक्वेंट को$relations
पर सभी संबंधित मॉडलों को इंस्टेंट करना होगा (relation1.relation2.relation3...
) हम जिस में रुचि रखते हैं उसे पाने के लिए श्रृंखला -getNestedRelated()
में यही होता है , बहुत सीधा। -
तो हमें कुछ ऐसा करने की ज़रूरत है:
// assuming relations 'relation1.relation2.relation3' $this->whereHas('relation1', function ($q) use ($id) { $q->whereHas('relation2', function ($q) use ($id) { $q->whereHas('relation3', function ($q) use ($id) { $q->where('id', $id); }); }); })->find($this->getKey()); // returns new instance of current model or null, thus cast to (bool)
-
चूंकि हम नहीं जानते कि संबंध कितना गहरा है, इसलिए हमें पुनरावर्तन का उपयोग करने की आवश्यकता है। हालांकि हम
whereHas
. को क्लोजर पास करते हैं , इसलिए हमें इसके शरीर के अंदर खुद को कॉल करने के लिए छोटी सी चाल का उपयोग करने की आवश्यकता है (वास्तव में हम इसे कॉल नहीं करते हैं, बल्कि इसे$callback
के रूप में पास करते हैंwhereHas
. तक विधि, चूंकि उत्तरार्द्ध दूसरे परम के रूप में बंद होने की अपेक्षा करता है) - यह उन अपरिचित लोगों के लिए उपयोगी हो सकता है अनाम पुनरावर्ती PHP फ़ंक्शन :// save it to the variable and pass it by reference $callback = function () use (&$callback) { if (...) // call the $callback again else // finish; }
-
हम क्लोजर
$relations
. को भी पास करते हैं (अब एक सरणी के रूप में) इसके तत्वों को अनशिफ्ट करने के लिए संदर्भ द्वारा, और जब हम उन सभी को प्राप्त करते हैं (जिसका अर्थ है कि हमने नेस्टेडwhereHas
), हम अंत मेंwhere
. डालते हैं दूसरेwhereHas
. के बजाय क्लॉज , हमारे$related
. को खोजने के लिए मॉडल। -
अंत में
bool
वापस आते हैं