2015-07-16 2 views
0

Введение
Hello. В настоящее время я создаю FacebookFeedParser, и на данный момент я пытаюсь создать метод в контроллере, который перечисляет страницы Facebook с наилучшим соотношением post/like от сегодняшнего дня к пользователю. Чтобы сделать это, я построил следующий запрос в чистом SQLОтносительная загрузка, при использовании отбор

SELECT pa.facebook_name, COUNT(po.id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(po.id) AS likesPerPost 
FROM facebook_posts po 
INNER JOIN facebook_pages pa ON pa.id = po.facebook_page_id 
WHERE CONVERT_TZ(`facebook_created_time`, 'UTC', 'Europe/Berlin') > '2015-07-16 00:00:00' 
GROUP by facebook_page_id 
ORDER BY SUM(likes)/COUNT(po.id) DESC; 

Что я теперь хотел сделать, чтобы преобразовать этот запрос в Laravel/красноречив.

Текущее состояние
У меня есть следующие классы в моем проекте

Контроллеры: PageController, PostController
Модели: FacebookPost, FacebookPage, BaseModel

FacebookPost и FacebookPage модели оба определяющие их отношение нс нравится эта

FacebookPage

/** 
* Defines the relation between FacebookPage and FacebookPost 
* One page can have multiple posts 
* 
* @see FacebookPage 
* @see FacebookPost 
* 
* @return \Illuminate\Database\Eloquent\Relations\HasMany 
*/ 
public function posts() 
{ 
    return $this->hasMany(FacebookPost::class); 
} 

FacebookPost

/** 
* Defines the association of this object with FacebookPage 
* One facebook_post belongs to one facebook_page 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo 
*/ 
public function page() 
{ 
    return $this->belongsTo(FacebookPage::class, 'facebook_page_id'); 
} 

В BaseModel, я определил сферу, которая будет использоваться несколько раз в проекте

/** 
* Query scope to get the database values for today 
* 
* @param $query 
* @return mixed 
*/ 
public function scopeToday($query) 
{ 
    return $query->whereRaw('CONVERT_TZ(`'. $this->createDateColumn .'`, "UTC", "'. env('APP_TIMEZONE') .'") > "' . Carbon::today()->toDateTimeString() . '"'); 
} 

И это запрос, который я создал для того, чтобы получить эти сообщения. фильтры

$posts = App\Models\FacebookPost::with('page') 
->selectRaw('COUNT(id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(id) AS likesPerPost') 
->today() 
->groupBy('facebook_page_id') 
->orderByRaw('SUM(likes)/COUNT(id) DESC') 
->get(); 

Проблема
Проблема у меня в настоящее время имеющий, в том, что, когда я пытаюсь восстановить выше запрос, я не получаю все поля, которые я хочу. Как только я добавлю select в Builder, массив relations с индексом page имеет значение NULL. Если я опустил метод select, я получаю FacebookPage, но я хочу иметь эти конкретные поля.

Теперь я получаю объект. Думаю, это потому, что я правильно использую Eloquent Builder? Не так ли возможно получить только поля, которые я хочу иметь? В результате я ожидаю, должен выглядеть следующим образом (в строке)

facebook_name | postCount | likes | likesPerPost 

McDonalds    1000    500   0.5 

Я также попробовал, как этот

$posts = App\Models\FacebookPost::with(['page' => function($query) { 
    $query->select('facebook_name'); 
    }]) 
->selectRaw('COUNT(id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(id) AS likesPerPost') 
->today() 
->groupBy('facebook_page_id') 
->orderByRaw('SUM(likes)/COUNT(id) DESC') 
->get(); 

мне нужно использовать DB класс вместо красноречив? Или что было бы лучшим решением для этой проблемы?

Альтернативное решение

$pages = DB::table('facebook_posts') 
      ->select(DB::raw('facebook_pages.facebook_name, COUNT(facebook_posts.id) AS postCount, SUM(likes) AS likes, ROUND(SUM(likes)/COUNT(facebook_posts.id)) AS likesPerPost')) 
      ->join('facebook_pages', 'facebook_posts.facebook_page_id', '=', 'facebook_pages.id') 
      ->whereRaw('CONVERT_TZ(`'. $this->createDateColumn .'`, "UTC", "'. env('APP_TIMEZONE') .'") > "' . Carbon::today()->toDateTimeString() . '"') 
      ->groupBy('facebook_page_id') 
      ->orderByRaw('ROUND(SUM(likes)/COUNT(facebook_posts.id)) DESC') 
      ->get(); 

Это, однако, работает. Будет ли это правильным решением для моего варианта использования?Я просто спрашиваю, имеет ли смысл использовать Eloquent здесь, поскольку я не пытаюсь получить объект, а данные из нескольких источников.

ответ

0

Если вы хотите с («страницы») работать при указании списка полей для извлечения с помощью выберите() вам нужно убедиться, что внешний ключ находится в списке, в противном случае Laravel не является возможность получения связанных моделей. Поэтому в вашем случае убедитесь, что page_id выведен из базы данных.

Смежные вопросы