Laravel 4查询关系关系

时间:2014-07-14 20:34:37

标签: php laravel-4 eloquent

我创建了4个数据库表:

工具
ID | NAME | TOOLTYPE_ID

Tooltype刀具
ID | NAME

Toolcategory
ID | NAME

Tool_Toolcategory
TOOL_ID | TOOLCATEGORY_ID

模型如下:

class Tool extends Eloquent  {

 public function toolCategories()
 {
    return $this->belongsToMany('ToolCategory', 'tool_toolcategory', 'tool_id', 'toolcategory_id');
 }

 public function tooltype()
 {
    return $this->belongsTo('ToolType');
 }   
}

class ToolType extends Eloquent {

 public function tools()
 {
    return $this->hasMany('Tool', 'tooltype_id');
 }
}

class ToolCategory extends Eloquent {
 public function tools()
 {
    return $this->belongsToMany('Tool', 'tool_toolcategory', 'tool_id', 'toolcategory_id');
 }   
}

好的,我的问题是根据具有特定工具类型的创建工具获取工具类别 示例我想要所有类别与“软件”类型的工具相关的类别。
我有点迷茫,我已经看过尝试在我的工具类别模型中使用范围,做类似的事情此:

public function scopeHasType($query, $type)
{
  return $query->whereHas('tools.tooltype', function($q) use ($type) 
  {
    $q->where('name', '=', $type);
  })->exists();
}


这没有真正起作用:)然后我尝试了这个

$categories = ToolCategory::whereHas('tools.tooltype', function($query)
{
  $query->where('tooltype_id', '=', 'Software');                
})->get();

再次没有运气。所以我希望这对某人有意义,他们可以把我推向正确的方向。提前谢谢。

2 个答案:

答案 0 :(得分:2)

雄辩的命名惯例说:

  1. ModelNames是StudlyCased&单数
  2. modelMethods是camelCased(关系动态属性需要这个)
  3. table_names是snake_cased&复数
  4. table_columns为snake_cased
  5. pivot_table是model1_model2 snake_cased singular(按字母顺序排列)
  6. 话虽如此,Eloquent for model ToolCategory会查找表tool_categories

    所以你需要在不符合约定的情况下指定表名(单数,而不是蛇形等):

    // for example Tool model
    protected $table = 'tool'; 
    

    此外,您需要将外键传递给关系定义,以便让Eloquent知道要查找的内容。但是你已经做了:

    // ToolType model
    public function tools()
    {
        // here Eloquent would look for tool_type_id (based on related model)
        return $this->hasMany('Tool', 'tooltype_id');
    }
    
    // Tool model
    public function tooltype()
    {
        // here Eloquent looks for tooltype_id by default (based on relation name)
        return $this->belongsTo('ToolType');
    }  
    

    现在,您的关系没有问题,有1个例外(键错误的顺序):

    class ToolCategory extends Eloquent {
     public function tools()
     {
        return $this->belongsToMany('Tool', 'tool_toolcategory', 'toolcategory_id', 'tool_id');
     }
    

    最后,whereHas不适用于嵌套关系(但请检查:https://github.com/laravel/framework/pull/4954),所以目前您需要这个:

    // ToolCategory model
    public function scopeHasType($query, $type) 
    {
      return $query->whereHas('tools', function ($q) use ($type) {
        $q->whereHas('tooltype', function($q) use ($type) {
          // use table prefix, since this is going to be join
          $q->where('tooltype.name', '=', $type);
        });
      });
    }
    

答案 1 :(得分:0)

您的代码存在许多问题,首先,每个模型都需要受保护的$ table变量,这样:

class Tool extends Eloquent {
    protected $table = 'tools';
    public function toolCategories(){
        return $this->belongsToMany('ToolCategory');
    }

    public function tooltype(){
        return $this->belongsTo('ToolType');
    }
}

class ToolType extends Eloquent{
    protected $table = 'tooltypes';
    public function tools(){
        return $this->hasMany('Tool');
    }
}

class ToolCategory extends Eloquent{
    protected $table = 'toolcategories';
    public function tools(){
        return $this->belongsToMany('Tool');
    }
}

此外,您无法以这种方式查询关系" model.related",您需要编写嵌套关系查询,如下所示:

public function scopeHasType($query, $type){
    return $query->whereHas('tools', function ($query) use ($type) {
        $query->whereHas('tooltype', function($query2) use ($type) {
            $query2->where('name', '=', $type);
        });
    });
}

另外,你正在查询错误的列,如果你需要$ type作为字符串,你会查询' name'而不是' tooltype_id',如果您需要$ type作为类型的实际ID,那么您可以查询' tooltype_id'。

最后,不要忘记在表中定义索引,此查询可能会变得非常慢。