Laravel: 如何从具有关系的 3 个表中获取数据
Laravel: How to get data from 3 tables with relationship
我有 3 个表:
Customers
- id
- 名字
Sales
- customer_id
- sale_date
Contacts
- customer_id
- contact_date
contacts
table 中没有任何更新操作。每个进程在 contacts
table 中打开一条新记录。所以,一个用户可以在 contacts
table.
中有多个记录
以下是我在模型中的关系:
Customer
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function sales()
{
return $this->hasMany(Sale::class);
}
Contact
public function customer()
{
return $this->belongsTo('App\Customer', 'customer_id');
}
Sale
public function customer()
{
return $this->belongsTo('App\Customer');
}
我想要 contacts
table 的最新记录,并使其与其他相关的 table 合并。
这是我试过的查询:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record){
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
});
return $result->get();
在 blade 文件中,我在 foreach
循环中得到了一些结果。但是,我无法从 sales
和 contacts
table 中获取相关数据。
@foreach($result as $item)
@foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
@foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
谁能帮我如何显示销售和联系日期?或者对如何提高此代码质量有任何想法?
我不确定,但您可以尝试执行以下操作吗:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record) {
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
}
])->get();
如果您想要联系人的最新记录,您可以在 Customer
模型上声明另一个关系,例如:
public function latest_contact()
{
return $this->hasOne(Contact::class)->latest('contact_date');
}
顺便说一句,如果你有一个 hasMany
并且使用的 外键 相同,你总是可以声明一个或多个 hasOne
附加关系。
通过这种方式,您可以使用您的 Customer
模型检索 latest_contact
eager loaded:
$customer = Customer::with('latest_contact')->find($id);
或者在您的查询中使用这种关系,例如:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
或者说:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
如果你愿意,你可以用额外的 where
:
声明 last_contact
public function latest_contact()
{
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
}
这样所有其他查询应该更容易。
希望对您有所帮助。
我有 3 个表:
Customers
- id
- 名字
Sales
- customer_id
- sale_date
Contacts
- customer_id
- contact_date
contacts
table 中没有任何更新操作。每个进程在 contacts
table 中打开一条新记录。所以,一个用户可以在 contacts
table.
以下是我在模型中的关系:
Customer
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function sales()
{
return $this->hasMany(Sale::class);
}
Contact
public function customer()
{
return $this->belongsTo('App\Customer', 'customer_id');
}
Sale
public function customer()
{
return $this->belongsTo('App\Customer');
}
我想要 contacts
table 的最新记录,并使其与其他相关的 table 合并。
这是我试过的查询:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record){
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
});
return $result->get();
在 blade 文件中,我在 foreach
循环中得到了一些结果。但是,我无法从 sales
和 contacts
table 中获取相关数据。
@foreach($result as $item)
@foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
@foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
谁能帮我如何显示销售和联系日期?或者对如何提高此代码质量有任何想法?
我不确定,但您可以尝试执行以下操作吗:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record) {
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
}
])->get();
如果您想要联系人的最新记录,您可以在 Customer
模型上声明另一个关系,例如:
public function latest_contact()
{
return $this->hasOne(Contact::class)->latest('contact_date');
}
顺便说一句,如果你有一个 hasMany
并且使用的 外键 相同,你总是可以声明一个或多个 hasOne
附加关系。
通过这种方式,您可以使用您的 Customer
模型检索 latest_contact
eager loaded:
$customer = Customer::with('latest_contact')->find($id);
或者在您的查询中使用这种关系,例如:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
或者说:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
如果你愿意,你可以用额外的 where
:
last_contact
public function latest_contact()
{
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
}
这样所有其他查询应该更容易。 希望对您有所帮助。