Laravel - 如何基于许多多态性关系中的标记来搜索?
-
21-12-2019 - |
题
我有一个表单设置,用文本输入和多选择输入。多选择输入有标签列表。标签被设置为多对多多态性关系。有助于使事情清晰,以下是我的表和型号的轮廓:
表:
org
id - integer
name - text
...
tags
id - integer
name - text
taggables
tag_id - integer
taggable_id - integer
taggable_type - text
.
模型:
class Org extends Eloquent
{
...
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
class Tag extends Eloquent
{
...
public function org()
{
return $this->morphedByMany('Org', 'taggable');
}
}
.
在我的routes.php文件中,我正在尝试执行如此...
$search = Input::get('keyword');
$searchTerms = explode(' ', $search);
$query = Org::query();
$fields = array('name', 'description', 'additional_info', 'website');
foreach ($searchTerms as $term)
{
foreach ($fields as $field)
{
$query->orWhere($field, 'LIKE', '%'. $term .'%');
}
}
if(Input::get('tags'))
{
$tags = Input::get('tags');
$query
->join('taggables', 'taggables.taggable_id', '=', 'org.id')
->where('taggables.taggable_type', '=', 'Org')
->join('tags', 'taggables.tag_id', '=', 'tags.id')
->groupBy('org.id');
foreach ($tags as $tag)
{
$query->orWhere('tags.id', '=', $tag);
}
}
$org = $query->get();
.
然而,这当然不起作用。关键字搜索工作正常,但我不确定如何添加查询,只能检索具有指定相关标记的行。 $标签变量是包含标记ID的数组。
我想只返回来自org表中的行,其中包含数组中指定的标记中的至少一个。
更新: 我已经更新了我的代码,它有点作品,但它似乎返回了标签,而不是关联的组织 - 尽管我觉得我正在接近。这是我添加的相关代码(或者只是看它上面):
$query
->join('taggables', 'taggables.taggable_id', '=', 'org.id')
->join('tags', 'taggables.tag_id', '=', 'tags.id')
->where('taggables.taggable_type', '=', 'Org')
->whereIn('tags.id', $tags);
.
更新2: 这似乎有效地工作,但由于某种原因,它检索标签的名称而不是组织名称...
$tags = Input::get('tags');
$query
->join('taggables', 'taggables.taggable_id', '=', 'org.id')
->where('taggables.taggable_type', '=', 'Org')
->join('tags', 'taggables.tag_id', '=', 'tags.id')
->groupBy('org.id');
foreach ($tags as $tag)
{
$query->orWhere('tags.id', '=', $tag);
}
. 解决方案
我得到了以下方式的关键字+标记搜索:
$query = Org::query();
// Search by keyword(s)
if(Input::get('keyword'))
{
$search = Input::get('keyword');
$searchTerms = explode(' ', $search);
$fields = array('org.name', 'org.description', 'org.additional_info', 'org.website');
foreach ($searchTerms as $term)
{
foreach ($fields as $field)
{
$query->orWhere($field, 'LIKE', '%'. $term .'%');
}
}
}
// Search for tag(s)
if(Input::get('tags'))
{
$tags = Input::get('tags');
$query
->join('taggables', 'taggables.taggable_id', '=', 'org.id')
->where('taggables.taggable_type', '=', 'Org')
->whereIn('taggables.tag_id', $tags)
->groupBy('org.id')
->orderBy(DB::raw('count(*)'), 'desc')
->orderBy('name', 'asc');
}
$org = $query->get();
.
如果为搜索输入了关键字和两个标签(例如),这将返回具有一个或多个标签的这些组织,包含与输入的关键字一样的单词,并将结果进行排序,以便为组织进行排序最初的标签将首先出现。
不隶属于 StackOverflow