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();
.
しかしもちろんこれは機能しません。キーワード検索は正常に機能しますが、指定された関連付けタグを持つ行のみを取得するクエリを追加する方法はわかりません。 $ TAGS変数は、タグのIDを含む配列です。
アレイに指定されている少なくとも1つのタグを持つ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();
.
検索にキーワードと2つのタグが入力されている場合、これは1つ以上のタグを持つ組織を返し、入力されたキーワードのような単語を含み、その結果を付けるように並べ替えます。最も一致するタグが最初に表示されます。
所属していません StackOverflow