2014-07-03 14 views
6

मैं Laravel 4. मुझे पता था कि के रूप में पर काम कर रहा हूँ, मैं सबक्वेरी कर सकते हैं:Laravel का डाटाबेस अनुकूलित करने के लिए कैसे क्वेरी बिल्डर (बेहतर सबक्वेरी बनाने)

Project::whereIn('project_id', function($q) { 
    $q->select('project_id') 
     ->from('company') 
     ->whereNull('deleted_at'); 
}); 

मैं जटिलताओं पाया, कि मैं यह कर सकते हैं ' subquery में स्कोप का उपयोग करें और soft_delete अक्षम करें मुझे स्रोत कोड को इतना बदल दें।

काश यह था:

Project::whereIn('project_id', function(&$q) { 
    $q = Company::select('project_id')->getQuery(); 
}); 

अब, मैं, गुंजाइश जोड़ सकते हैं आसानी से soft_delete अक्षम करें।

मैंने कोशिश की, और पाया एक समाधान है कि मैं Laravel का डाटाबेस \ क्वेरी \ बिल्डर कोड, समारोह whereInSub, लाइन 786.

call_user_func($callback, $query = $this->newQuery()); 

में परिवर्तित करना होगा:

$query = $this->newQuery(); 
call_user_func_array($callback, array(&$query)); 

यह संशोधित करने के लिए हानिकारक है लैरवेल ढांचे के विक्रेता। तो मैं पूछना चाहता हूं कि इसे सुरक्षित तरीके से कैसे किया जाए।

क्षमा करें क्योंकि मेरी खराब अंग्रेजी।

पढ़ने के लिए धन्यवाद।

उत्तर

12

ओह! यह काफी मुश्किल है क्योंकि आपका मॉडल Eloquent का विस्तार करेगा, फिर EloquentIlluminate\Database\Query\Builder का उपयोग करता है।

लेकिन क्या मैंने देखा है कि वास्तव में Eloquentapp/config/app.php फ़ाइल में एक उपनाम है। तो आप इन चरणों का पालन कर क्या कर सकते हैं।

  1. अपने कस्टम whereInSub() साथ MyQueryBuilder को Illuminate\Database\Query\Builder बढ़ाएँ।
  2. Illuminate\Database\Eloquent\ModelMyModel पर विस्तार करें और इसे अपने MyQueryBuilderuse बनाते हैं।
  3. Eloquentapp/config/app.php में अपने नए MyModel कक्षा में सेट करें।

कुछ इस तरह:

MyQueryBuilder.php:

use Closure; 
use Illuminate\Support\Collection; 
use Illuminate\Database\ConnectionInterface; 
use Illuminate\Database\Query\Grammars\Grammar; 
use Illuminate\Database\Query\Processors\Processor; 

class MyQueryBuilder extends Illuminate\Database\Query\Builder 
{ 
    protected function whereInSub($column, Closure $callback, $boolean, $not) 
    { 
     $type = $not ? 'NotInSub' : 'InSub'; 

     $query = $this->newQuery(); // Your changes 
     call_user_func_array($callback, array(&$query)); // Your changes 

     $this->wheres[] = compact('type', 'column', 'query', 'boolean'); 

     $this->mergeBindings($query); 

     return $this; 
    } 
} 

MyModel.php:

use DateTime; 
use ArrayAccess; 
use Carbon\Carbon; 
use LogicException; 
use Illuminate\Events\Dispatcher; 
use Illuminate\Database\Eloquent\Relations\Pivot; 
use Illuminate\Database\Eloquent\Relations\HasOne; 
use Illuminate\Database\Eloquent\Relations\HasMany; 
use Illuminate\Database\Eloquent\Relations\MorphTo; 
use Illuminate\Support\Contracts\JsonableInterface; 
use Illuminate\Support\Contracts\ArrayableInterface; 
use Illuminate\Database\Eloquent\Relations\Relation; 
use Illuminate\Database\Eloquent\Relations\MorphOne; 
use Illuminate\Database\Eloquent\Relations\MorphMany; 
use Illuminate\Database\Eloquent\Relations\BelongsTo; 
// use Illuminate\Database\Query\Builder as QueryBuilder; 
use Illuminate\Database\Eloquent\Relations\MorphToMany; 
use Illuminate\Database\Eloquent\Relations\BelongsToMany; 
use Illuminate\Database\Eloquent\Relations\HasManyThrough; 
use Illuminate\Database\ConnectionResolverInterface as Resolver; 
use MyQueryBuilder as QueryBuilder; // MyModel should now use your MyQueryBuilder instead of the default which I commented out above 

abstract class MyModel extends Illuminate\Database\Eloquent\Model 
{ 

} 

एप्लिकेशन/config/app.php:

'aliases' => array(
    ... 
    'Eloquent'  => 'MyModel', 
    ... 
); 

ध्यान दें कि मैं वहाँ क्योंकि "use" keyword does not get inheriteduse की लंबी सूची में डाल दिया। इसके अलावा मैंने सादगी के लिए नामस्थान में MyQueryBuilder और MyModel नहीं रखा। हमारे द्वारा उपयोग किए जाने वाले लैरवेल संस्करणों के आधार पर मेरी use सूची आपके से भिन्न हो सकती है, इसलिए कृपया उपयोगों की भी जांच करें।

+4

मैंने अपना प्रश्न संपादित किया क्योंकि मुझे समाधान मिला। संरक्षित फ़ंक्शन को ओवरराइड करने की आवश्यकता है नया क्लास MyModel –

+0

में "उपयोग" सूचियों को शामिल करने की आवश्यकता नहीं है जब तक आप वास्तव में ... अपने उप-वर्ग में उनका उपयोग नहीं कर रहे हैं। इस मामले में आपको केवल अपने MyQueryBuilder की आवश्यकता है, जिसका उपयोग नए BaseQueryBuilder() के ओवरराइड संस्करण में @ LêTrầnTiếnTrung के रूप में सटीक रूप से इंगित किया जाएगा। – LePhleg

संबंधित मुद्दे