Laravel Eloquent 通过中间 table 从两个 table 获取数据

Laravel Eloquent get data from two tables through an intermediate table

我有以下三个表:

users
    id - integer
    name - string

tracker_sessions
    id - integer
    user_id - integer
    geoip_id - integer

tracker_geoip
    id - integer
    country - string

这些是我的模型:

class User extends Authenticatable
{
    public function tracker_geoip(){
        return $this->hasManyThrough('App\TrackerGeo', 'App\TrackerSession', 'geoip_id', 'id', 'id');
    }
    public function tracker_sessions(){
        return $this->hasMany('App\TrackerSession');
    }
}

class TrackerGeo extends Model
{
    protected $table = 'tracker_geoip';
}

class TrackerSession extends Model
{
    protected $table = 'tracker_sessions';
}

是否可以使用 Eloquent 得到这个结果? :

0 => [
     'name' => 'John Smith',
     'geoip' => ['id' => 12, 'country' => 'Greenland']
]

我已经试过了:

$usersWithGeo = App\User::with('tracker_geoip')->get()->toArray();

这会 return 一个用户信息数组,但 tracker_geoip 子数组始终为空,即使表中有记录也是如此。

查看您的 table 结构,tracker_geoip 的关系实际上应该是 belongsToMany 而不是 hasManyThrough

return $this->belongsToMany('App\TrackerGeo', 'tracker_sessions', 'user_id', 'geoip_id')->distinct();

希望对您有所帮助!

试试下面的代码(避免关系):

class TrackerSession extends Model
{
    public function getGeoipNameAttribute(){
        return TrackerGeo::where('id', $this->attributes['geoip_id'])->first(); //you can stop here or add ->country; to get only the country name
    };
}

上述方法检索具有给定 ID 的 TrackerGeo 集合的国家/地区名称。

现在您需要的是获取给定用户的所有跟踪器会话。所以在用户模型中我们有:

public function getTrackerSessionAttribute(){
    return TrackerSession::where('user_id', %this->attributes['id'])->get() //or first() depends on the number of records you want to retrieve.
}

在您看来,您可以执行以下操作:

$user->tracker_session->geoip_name // ->country depends on the return result

如果您使用 first() Eloquent 方法仅检索到 1 条记录,或者

@foreach($user->tracker_session as $session)
    {{$session->geoip_name}} // {{$session->geoip_name->country}} depends on the return result
@endforeach

请注意,您可以使用方法的 snake case 名称作为主模型的属性来访问集合。