簡體   English   中英

Laravel Eloquent:搜索具有一系列關系的模型

[英]Laravel Eloquent: Search models with array of relationships

我在雄辯的模型Candidate中具有以下作用域,讓我們獲取一個Collection,其中每個項目都有一個與Collections $fields$categories相匹配的關系。

也就是說,它讓我得到了具有所有$fields$categories的候選人集合。

class Candidate extends Model {
    public function scopeMatching($query, $fields, $categories ) {
        return $query->get()->filter( function ( $candidate ) use ( $categories, $fields ) {
            $outcome = false;
            foreach ($categories as $category){
                $outcome = $candidate->categories->contains( $category );
            }
            foreach ($fields as $field){
                $outcome = $candidate->fields->contains( $field );
            }
            return $outcome;
        });
    }
    public function user() {
        return $this->belongsTo( User::class );
    }
    public function jobs() {
        return $this->belongsToMany(Job::class);
    }
    public function categories() {
        return $this->belongsToMany(Category::class);
    }
    public function fields() {
        return $this->belongsToMany(Field::class);
    }
}

測試方法的用法示例:

    // Pick 2 random categories
    $categories = Category::all()->random( 2 );

    // Pick 5 random fields.
    $fields = Field::all()->random( 5 );

    // Pick a random candidate.
    $candidate = Candidate::all()->random();

    // Attach categories and fields to candidate.
    $candidate->categories()->attach( $categories );
    $candidate->fields()->attach( $fields );

    // Filter candidates to get only matching ones.
    $candidates = Candidate::with(['fields','categories'])->matching($fields, $categories);

它工作正常,但我想知道這是否是最好的方法。 是否有一種更好的,更“雄辯的”的方式來執行此操作而不使用兩個foreach循環?

$collection = collect([
    'field1' => 'value1', 
    'field2' => 'value2',
    'field3' => 'value3', 
]);

$outcome = $collection->contains(function ($value, $key) use ($category) {
  return $value == $category;
});

最好將whereHaswhereHas方法與whereIn一起whereIn因為它們將使用SQL而不是PHP for循環,這將最終提高效率。

$query->whereHas('fields', function($q) use($fields) {
    $q->whereIn('id', $fields->pluck('id'));
})->orWhereHas('categories', function($q) use($categories) {
    $q->whereIn('id', $categories->pluck('id');
})->get();

該查詢與獲取至少有一個字段關系誰的id是在所有考生fields數組或具有至少一個類別的關系誰的ID是在categories陣列。

您可以在文檔Laravel Query Builder文檔中閱讀有關這些方法的更多信息。

Josh建議的解決方案可行 ,但是我做了一些調整,因為我想匹配所有字段,但要匹配ANY類別。

public function scopeMatching( Builder $query, Collection $fields, Collection $categories ) {
    foreach ( $fields as $field ) {
        $query = $query->whereHas( 'fields', function ( Builder $q ) use ( $field ) {
            $q->where( 'id', $field->id );
        } );
    }
    $query->whereHas( 'categories', function ( Builder $q ) use ( $categories ) {
        $q->whereIn( 'id', $categories->pluck( 'id' ) );
    });

    return $query->get();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM