2014-09-27 44 views
4

说我想存储有关客户的各种数据位,所以我有两个型号由枢轴表链接,存储客户的值在枢轴表中的每个数据字段类型:Laravel范围由枢数据值

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

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

所以我的表是客户,customer_datafield,数据域。

如何在客户中设置查询范围以查找特定数据字段值为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); 
    } 
} 

行我已经尝试了一些方法,但没有任何运气歌厅一个工作。任何建议非常感谢!

回答

8

单个固定支点场雄辩的语言:

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(); 

可以改变它以相同的方式如上面第二实施例。

+0

辉煌,一个详细的解答和伟大工程。非常感谢! – Rob 2014-09-27 13:19:03

0

注:Laravel 5,你可以简单地使用:

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

我似乎使用这种方法出现错误。 'return $ query-> wherePivot('status','=','planned');'这一行返回未找到的'pivot'列。 – Gokigooooks 2016-02-12 20:38:34

+0

@Gokigooooks wherePivot只能在belongsTomany关系中使用,因此您的$查询是b2m的一个实例。 – 2016-02-13 21:21:11

+0

嘿我有一个belongsToMany关系..我诉诸使用'where('model.relationmodel','=','计划)'我很高兴laravel有很多选项:)谢谢 – Gokigooooks 2016-02-15 09:57:32