Вы можете иметь таблицу базы данных без модели Eloquent, но не наоборот. Тем не менее, нет правила против создания более 1 модели на стол. Не совсем стандартная практика.
Я экспериментировал с созданием модели, которая наследовала бы от другой модели, но метод загрузки не сработал, как ожидалось, поэтому я отбросил его.
Я думаю, вы можете получить всю информацию, полученную из этого запроса, с помощью аксессоров в вашей Client
модели. Поскольку в вашем запросе нет условия where, scope не является действительно необходимым, но это также можно сделать с помощью этого.
ВАРИАНТ 1: Средства доступа
# App\Client
class Client extends Model
{
// Standard Eloquent relationship
public function messages()
{
return $this->hasMany(App\Message::class);
}
// Accessor $client->client_name
public function getClientNameAttribute()
{
return $this->name;
}
// Accessor $client->last_message
public function getLastMessageAttribute()
{
// Load relationship only if it hasn't been loaded yet
if(!$this->relationshipLoaded('messages'))
$this->load('messages');
// use max() method from collection to get the results
return $this->messages->max('created_at');
}
// Accessor $client->has_new_for_client
public function getHasNewForClientAttribute()
{
// Load relationship only if it hasn't been loaded yet
if(!$this->relationshipLoaded('messages'))
$this->load('messages');
return $this->messages->count() > $this->messages->sum('viewed_by_client');
}
// Accessor $client->has_new_for_user
public function getHasNewForUserAttribute()
{
// Load relationship only if it hasn't been loaded yet
if(!$this->relationshipLoaded('messages'))
$this->load('messages');
return $this->messages->count() > $this->messages->sum('viewed_by_user');
}
}
И тогда вы можете получить динамический доступ ко всем свойствам
$dialog = Client::withCount('messages')->find($id);
$dialog->client_name;
$dialog->messages_count;
$dialog->has_new_for_client;
$dialog->has_new_for_user;
$dialog->last_message;
Однако, если вы конвертируете $dialog
в формат массива или json, средства доступа будут потеряны, если вы не добавите их . Таким же образом вы можете скрыть атрибуты, которые вы не хотите показывать.
Это можно сделать глобально для модели
protected $appends = ['client_name', 'has_new_for_client', 'has_new_for_user', 'last_message'];
protected $hidden = ['name'];
или локально для запроса
$dialog->setHidden(['name']);
$dialog->setAppends(['client_name', 'has_new_for_client', 'has_new_for_user', 'last_message'];
ВАРИАНТ 2: Области запросов
# App\Client
class Client extends Model
{
public function scopeDialog($query)
{
$query->select('name as client_name')
->withCount('messages') // the default name will be messages_count
->selectRaw('max(m.created_at) as last_message')
->selectRaw('count(m.id) > sum(m.viewed_by_client) as has_new_for_client')
->selectRaw('count(m.id) > sum(m.viewed_by_user) as has_new_for_user')
->join('messages as m', 'm.client_id', 'clients.id')
->groupBy('clients.id');
}
}
А затем просто назовите его так, как если бы вы использовали любую область действия Client :: dialog () -> ...
ВАРИАНТ 3: Просто используйте те методы, которые уже доступны, вместо того, чтобы писать больше логики
$dialog = Client::with('messages')->find($id);
// client_name
$dialog->name
// messages_count
$dialog->messages->count()
// last_message
$dialog->messages->max('created_at')
// has_new_for_client
($dialog->messages->count('id') > $dialog->messages->count('viewed_by_client'))
// has_new_for_user
($dialog->messages->count('id') > $dialog->messages->count('viewed_by_user'))