Laravel Eloquent: hasManyThrough 还是其他?
Laravel Eloquent: hasManyThrough or Something Else?
在 Laravel 5.7 我已经阅读了 Has Many Through documentation 但我仍然不能正确地使用它来处理我的情况。
这是数据库:
Analytics
id
data
subscriber_id
Subscribers
id
city_id
Cities
id
name
我需要 Analytics 模型从 Analytics
和 subscribers.id
和 cities.name
获取数据
我做了什么:
连接的分析和订阅者模型
<?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');
}
}
发出一个请求,从 Analytics
table 获取数据,订阅者数据:
$results = Analytics::where('survey_id', '4')
->with('subscriber')
->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');
}
}
我不确定我是否正确理解了您的要求。您想获取给定 City
的 Subscribers
中的所有 Analytics
吗?或者您想要分析订阅者的城市名称吗?无论哪种方式,这里都有两种解决方案。
获取给定城市订阅者的所有分析:
$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();
或者要获取分析记录的城市名称,您有两种选择。一种是对关系使用 Laravel 预加载,这可行,但可能会将大量不必要的数据加载到内存中:
$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;
}
另一种是自己加入table并且select只需要必要的数据:
$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;
}
请注意,您可以使用 select('analytics.*', 'cities.name')
,但这将覆盖 analytics
table 的 name
列 selected(如果存在)。所以最好使用 as col_alias
.
的列别名
感谢 Nick Surmanidze 和 Namoshek 的回答!
我昨晚找到了它的工作方式:
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');
}
}
而需要的结果可以这样得到:
$results = Analytics::where('survey_id', '4')
->with(['subscriber' => function($i){
$i->with(['subscriberCity']);
}])
->whereDate('created_at', '>=', $last_survey_date)
->orderBy('data')
->get();
在 Laravel 5.7 我已经阅读了 Has Many Through documentation 但我仍然不能正确地使用它来处理我的情况。
这是数据库:
Analytics
id
data
subscriber_id
Subscribers
id
city_id
Cities
id
name
我需要 Analytics 模型从 Analytics
和 subscribers.id
和 cities.name
我做了什么:
连接的分析和订阅者模型
<?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');
}
}
发出一个请求,从 Analytics
table 获取数据,订阅者数据:
$results = Analytics::where('survey_id', '4')
->with('subscriber')
->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');
}
}
我不确定我是否正确理解了您的要求。您想获取给定 City
的 Subscribers
中的所有 Analytics
吗?或者您想要分析订阅者的城市名称吗?无论哪种方式,这里都有两种解决方案。
获取给定城市订阅者的所有分析:
$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();
或者要获取分析记录的城市名称,您有两种选择。一种是对关系使用 Laravel 预加载,这可行,但可能会将大量不必要的数据加载到内存中:
$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;
}
另一种是自己加入table并且select只需要必要的数据:
$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;
}
请注意,您可以使用 select('analytics.*', 'cities.name')
,但这将覆盖 analytics
table 的 name
列 selected(如果存在)。所以最好使用 as col_alias
.
感谢 Nick Surmanidze 和 Namoshek 的回答! 我昨晚找到了它的工作方式:
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');
}
}
而需要的结果可以这样得到:
$results = Analytics::where('survey_id', '4')
->with(['subscriber' => function($i){
$i->with(['subscriberCity']);
}])
->whereDate('created_at', '>=', $last_survey_date)
->orderBy('data')
->get();