Я совершенно новичок в Laravel. Недавно я написал запрос к базе данных, который отлично работает и выглядит следующим образом:
function search($keywords, $lang)
{
if(count($keywords)<1)
return [];
$pages = DB::table('pages')
->select(explode(',','pages.id,pages.updated_at,pages.created_at,page_translations.title,page_translations.description'))
->selectSub(function($query){
$query->selectRaw("'pages'");
},'content_type')
->join('page_translations','page_translations.page_id','=','pages.id')
->whereNull('pages.deleted_at')
->whereNull('page_translations.deleted_at')
->where([
['pages.published','=',1],
['page_translations.locale','=',$lang],
['page_translations.active','=',1],
])
->where(function($query) use ($keywords) {
// Title
$query->where(function($subquery) use ($keywords) {
$subquery->where('page_translations.title','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords); $c++)
$subquery->where('page_translations.title','LIKE','%'.$keywords[$c].'%');
});
// Description
$query->orWhere(function($subquery) use ($keywords) {
$subquery->where('page_translations.description','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords); $c++)
$subquery->where('page_translations.description','LIKE','%'.$keywords[$c].'%');
});
// Block Content
$query->orWhereIn('pages.id',function($subquery) use ($keywords) {
$subquery->select('blockable_id')
->from('blocks')
->where('blockable_type','=','App\\\\Models\\\\Page')
->where(function($blockquery) use ($keywords) {
$blockquery->where('content','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords);$c++)
$blockquery->where('content','LIKE','%'.$keywords[$c].'%');
});
});
});
$articles = DB::table('articles')
->select(explode(',','articles.id,articles.updated_at,articles.created_at,article_translations.title,article_translations.description'))
->selectSub(function($query){
$query->selectRaw("'articles'");
},'content_type')
->join('article_translations','article_translations.article_id','=','articles.id')
->whereNull('articles.deleted_at')
->whereNull('article_translations.deleted_at')
->where([
['articles.published','=',1],
['article_translations.locale','=',$lang],
['article_translations.active','=',1],
])
->where(function($query) use ($keywords) {
// Title
$query->where(function($subquery) use ($keywords) {
$subquery->where('article_translations.title','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords); $c++)
$subquery->where('article_translations.title','LIKE','%'.$keywords[$c].'%');
});
// Description
$query->orWhere(function($subquery) use ($keywords) {
$subquery->where('article_translations.description','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords); $c++)
$subquery->where('article_translations.description','LIKE','%'.$keywords[$c].'%');
});
// Block Content
$query->orWhereIn('articles.id',function($subquery) use ($keywords) {
$subquery->select('blockable_id')
->from('blocks')
->where('blockable_type','=','App\\\\Models\\\\Article')
->where(function($blockquery) use ($keywords) {
$blockquery->where('content','LIKE','%'.$keywords[0].'%');
for($c=1;$c<count($keywords);$c++)
$blockquery->where('content','LIKE','%'.$keywords[$c].'%');
});
});
})
->union($pages)
->orderBy('updated_at','desc')
->get();
return $articles->toArray();
}
В основном эта функция получает массив $keywords
. Затем запрос будет искать любые page
или любые article
, имеющие ALL ключевые слова в title, description or content
в активном translation tables or block tables
. Я использую UNION, чтобы помочь мне объединить результаты двух разных типов контента и упорядочить их по времени последнего обновления.
Когда я смотрю на этот код, он НЕ выглядит как идиоматический c laravel способ делать вещи. Как будто я только что написал Raw SQL. Кто-нибудь может подсказать, как правильно использовать Laravel / Eloquent для выполнения вышеуказанных функций?