我创建了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();
再次没有运气。所以我希望这对某人有意义,他们可以把我推向正确的方向。提前谢谢。
答案 0 :(得分:2)
雄辩的命名惯例说:
StudlyCased
&单数camelCased
(关系动态属性需要这个)snake_cased
&复数snake_cased
model1_model2
snake_cased singular(按字母顺序排列)话虽如此,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'。
最后,不要忘记在表中定义索引,此查询可能会变得非常慢。