2016-04-09 13 views
1

İki modelim var: App \ Song (aittir) \ Appliance (App Store) ve App \ Host (hasMany App \ Song). yeniden kullanılabilirliği içinIlişkilerin Üzerinde Makul Sorgulama Kapsamı

$songs = Song::whereHas('host', function($query) { 
       $query->where('skip_threshold', '>', \DB::raw('songs.attempts')) 
         ->where('active', 1); 
      }) 
->whereNull('downloaded') 
->get(); 

Bir sorgu alan (lar) dönüşmesini istiyoruz:

benim Kontrolör aşağıdaki sorgu var.

Eloquent'e oldukça yeni geldim, bu yüzden bunu yapmanın doğru yolu olduğundan emin değilim, çünkü bu iki Modelin herhangi bir sonuç döndürmemesi (olması gereken yerde).

Song.php

public function scopeEligable($query) 
{ 
    $query->where('skip_threshold', '>', \DB::raw('songs.attempts')); 
} 

public function scopeActiveHost($query) 
{ 
    $query->where('active', 1); 
} 

public function scopeInDownloadQueue($query) 
{ 
    $query->whereNull('downloaded'); 
} 
+0

o sorgu kapsamları çağırmak için kullandığınız denetleyicinizdeki kod nedir? (bu sonuçlar geri dönmüyor?) – dangel

+0

'Song :: eligable() -> activehost() -> indownloadqueue() -> get();' – Imran

+1

tüm kapsamlarınızda 'return' olmalıdır.' 'return $ '; query-> whereNull ('indirilen'). Kapsamlar her zaman bir sorgu oluşturucu örneğini döndürmelidir. https://laravel.com/docs/5.1/eloquent#query-scopes – dangel

cevap

2

Onların ait Modeller içine kapsamları koymalıyız. İlk sorguda baktığımızda scopeEligable kapsamları ve scopeActiveHostHost modeline aittir, bu nedenle Host modeline içine taşıyabilirsiniz gerekir, ardından böyle kapsamları kullanarak sorgu kullanmak mümkün olacak:

$songs = Song::whereHas('host', function($query) { 
    $query->eligable()->activeHost(); 
})->inDownloadedQueue()->get(); 

ve zaten sivri Yorum, her bir kapsam için return eklemelisiniz, böylece amaçlanan şekilde kullanılabilirler. Eğer daha kısa, sen Song modelinde yeni ilişkiyi yaratabilecek kullanarak yapmak istiyorsanız

DÜZENLEME

: yani şimdi

public function activeHost() 
{ 
    return $this->belongsTo(Host:class)->eligable()->activeHost(); 
} 

, yazabilirsiniz:

$songs = Song::whereHas('activeHost')->inDownloadedQueue()->get(); 
+0

Bu beklendiği gibi çalışıyor, ancak bu hala üç satırlık kod gerektiriyor, basitlik kodunda bunun tek bir satıra kısaltılabileceği bir yol var mı? – Imran

+0

@Imran Lütfen düzenlememe bak –

+0

Merhaba Marcin, Kodu şimdi kullanıyorum ve beklendiği gibi çalışmıyor görünüyor. Ben -> toSql() 'işlevini kullanarak hata ayıklamak ve aşağıdaki SQL oluşturulan almak için denedim:' var olan "şarkıları" dan * seçin * ("hosts" dan "hosts" seçin *. "Host_id" = "hosts". "id" ve "skip_threshold"> songs.attempts ve "active" =?) ve "indirilen" null'dır. Herhangi bir fikir? – Imran

0

Sanırım 2 model hakkında yanılıyorsunuz. Bu

Song.php çalışması gerektiğini düşünüyorum

public function scopeEligable($query, $active) { 
    return $query->whereHas('host', function($q) { 
     $q->where('skip_threshold', '>', \DB::raw('songs.attempts'))->where('active', $active); 
    }) 
} 

public function scopeInDownloadQueue($query) 
{ 
    $query->whereNull('downloaded'); 
} 

Kullanımı

$songs = Song::eligable(true)->inDownloadQueue()->get();