Laravel Eloquent:hasManyThrough还是其他什么?

In Laravel 5.7 I have read the Has Many Through documentation but I still can't use it correctly for my case.

Here's the DB:

Analytics

    id
    data
    subscriber_id

Subscribers

    id
    city_id

Cities

    id
    name

I need the Analytics model to get data from Analytics with subscribers.id and cities.name

What I have done:

Connected Analytics and Subscribers models

<?php

class Analytics extends Model
{
    public function subscriber()
    {
        return $this->belongsTo('App\Models\Subscriber');
    }
}

class Subscriber extends Model
{
    public function analytics()
    {
        return $this->hasMany('App\Models\Analytics');
    }
}

Made a request that gets the data from the Analytics table with subscribers data:

$results = Analytics::where('survey_id', '4')
    ->with('subscriber')
    ->whereDate('created_at', '>=', $last_survey_date)
    ->orderBy('data')
    ->get();

If anybody has any ideas how to get city names, please, share it.

Thank you Nick Surmanidze and Namoshek for your answers! I have found the way it works last night:

class Subscriber extends Model
{
    public function analytics()
    {
        return $this->hasMany('App\Models\Analytics');
    }

    public function subscriberCity()
    {
        return $this->belongsTo('Modules\Directories\Entities\City', 'city_id', 'id');
    }

}


class City extends Model
{
    public function subscriber()
    {
        return $this->hasMany('App\Models\Subscriber');
    }
}

And the needed result can be get by this way:

$results = Analytics::where('survey_id', '4')
    ->with(['subscriber' => function($i){
            $i->with(['subscriberCity']);
        }])
    ->whereDate('created_at', '>=', $last_survey_date)
    ->orderBy('data')
    ->get();
  // maybe this will work for you?
  class Analytics extends Model
    {
        public function subscriber()
        {
            return $this->belongsTo('App\Models\Subscriber');
        }

        public function cities() {
            return $this->hasManyThrough('App\City', 'App\Subscriber');
        }   

    }

I'm not sure if I understood your request correctly. Do you want to get all Analytics of Subscribers of a given City? Or do you want the city name of an analytics' subscriber? Either way, here are both solutions.

To get all analytics for subscribers of a given city:

$city = 'Vienna';

$results = Analytics::query()
    ->with('subscriber')
    ->whereHas('subscriber', function ($query) use ($city) {
        $query->whereHas('city', function ($query) use ($city) {
            $query->where('name', $city);
        });
    })
    ->where('survey_id', '4')
    ->whereDate('created_at', '>=', $last_survey_date)
    ->orderBy('data')
    ->get();

Or to get the city name for an analytics record, you have two options. One is to use the Laravel eager loading for relationships, which works, but will probably load a lot of unnecessary data into memory:

$results = Analytics::query()
    ->with('subscriber.city') // you can nest relationships as far as they go
    ->where('survey_id', '4')
    ->whereDate('created_at', '>=', $last_survey_date)
    ->orderBy('data')
    ->get();

foreach ($results as $analytics) {
    $city = $analytics->subscriber->city->name;
}

The other is to join the tables yourself and select only the necessary data:

$results = Analytics::query()
    ->join('subscribers', 'subscribers.id', '=', 'analytics.subscriber_id')
    ->join('cities', 'cities.id', '=', 'subscribers.city_id')
    ->where('analytics.survey_id', '4')
    ->whereDate('analytics.created_at', '>=', $last_survey_date)
    ->orderBy('analytics.data')
    ->select('analytics.*', 'cities.name as city_name')
    ->get();

foreach ($results as $analytics) {
    $city = $analytics->city_name;
}

Beware that you could use select('analytics.*', 'cities.name'), but this will override a name column selected of the analytics table if one exists. So it is better to use a column alias with as col_alias.