首页 文章

Laravel Scope通过数据透视数据值

提问于
浏览
6

假设我想存储有关客户的各种数据,因此我有两个由数据透视表链接的模型,在数据透视表中存储每个数据字段类型的客户值:

Customer {
    public function datafields()
    {
        return $this->belongsToMany('Datafield')->withPivot('value');
    }
}

Datafield {
    public function customers()
    {
        return $this->belongsToMany('Customer')->withPivot('value');
    }

所以我的表是客户,customer_datafield,datafields .

如何在客户中设置查询范围,以查找具有特定数据字段x值的所有客户?

有点像

Customer {
    public function datafields()
    {
        return $this->belongsToMany('Datafield')->withPivot('value');
    }
    public function scopeSearch($query, $searchfor)
    {
        return $query->datafields()->pivot()
            ->where('value', $searchfor)
            ->where('datafield_id', 123);
    }
}

我尝试了一些方法,但没有任何运气让人工作 . 任何建议非常感谢!

2 回答

  • 2

    单个固定枢轴字段的雄辩方式:

    public function scopeDataValue($query, $search)
    {
        $pivot = $this->datafields()->getTable();
    
        $query->whereHas('datafields', function ($q) use ($search, $pivot) {
            $q->where("{$pivot}.value", $search);
        });
    }
    
    // usage
    Model::
    

    这为您提供更多功能和灵活性:

    public function scopeDataValues($query, array $search, $bool = 'and')
    {
        $pivot = $this->datafields()->getTable();
    
        $query->whereHas('categories', function ($q) use ($search, $pivot, $bool) {
            $q->where(function ($q) use ($search, $pivot, $bool) {
                foreach ($search as $field => $value)
                {
                    $q->where("{$pivot}.{$field}", '=', $value, $bool);
                }
            });
        });
    }
    
    // usage
    Model::dataValues(['value' => 'findMe', 'otherField' => 'findMeToo'])->get();
    
    Model::dataValues(['value' => 'findMe', 'otherField' => 'orFindMe'], 'or')->get();
    

    您可能想在第二个闭包中使用带有数组值的 where 而不是 foreach ,但是它可能无法按预期工作,因为字段不会以表名为前缀 .


    另一种解决方案是使用简单的 join

    public function scopeDataValue($query, $search)
    {
        $pivot = $this->datafields()->getTable();
    
        // first get array of already joined table
        $base = $query->getQuery();
        $joins = array_fetch((array) $base->joins, 'table');
    
        $foreignKey = $this->categories()->getForeignKey();
    
        // if table has not been joined, let's do it
        if ( ! in_array($pivot, $joins))
        {
            $query->join($pivot, $this->getQualifiedKeyName(), '=', $foreignKey);
        }
    
        $query->where("{$pivot}.correct", $search);
    }
    
    // usage
    Model::dataValue(2)->take(..)->where(..)->dataValue(5)->get();
    

    你可以像上面第二个例子一样改变它 .

  • 11

    注意:在Laravel 5上你可以简单地使用它:

    $query->wherePivot('pivotcolumn','=', $search);
    

相关问题