逻辑
一家公司有很多用户。每个用户都有很多提醒。每个警报 属于一个地方。
我想在表格中显示每个用户的提醒以及提醒的相应位置。最好在每个警报一侧使用用户名。
公司和用户通过pivotTable链接,即belongsToMany关系。 警报属于一个位置。 该位置有很多警报。
警报模型:
public function location()
{
return $this->belongsTo('Location');
}
public function user()
{
return $this->belongsTo('User');
}
用户模型:
public function companies()
{
return $this->belongsToMany('Company')->withTimestamps();
}
public function alerts()
{
return $this->hasMany('Alert');
}
公司型号:
public function users()
{
return $this->belongsToMany('User')->withTimestamps();
}
位置模型:
public function alerts()
{
return $this->hasMany('Alert');
}
到目前为止,我在控制器中有这个:
public function getAdminIndex()
{
$company_id = User::find(Auth::user()->id)
->companies()
->first()
->id;
$alerts = Company::with('users.alerts.location')
->where('id', '=', $company_id)
->get();
$this->layout->content = View::make('agents.admin.index',
array('alerts' => $alerts));
}
我如何解释查询
转到视图,已经执行的MYSQL查询似乎是正确的,但是,我不能在我的生活中打印出数据,例如,在每个警报中。
我对查询进行成像将基于(基于模型):
@foreach($alerts as $alert)
<td>{{$alert->users->alerts->location->address_1}}</td>
@endforeach
但每次我遇到一个或另一个错误时 - 最常见的错误是Trying to get property of non-object
。
如何显示每个用户的提醒及其各自的位置,我们将非常感谢您的帮助。
答案 0 :(得分:2)
正如我在您之前的问题中所述的评论中所述:您必须了解从查询(模型集或模型集)返回的内容以及动态属性(加载关系)的工作原理。 为了让你完全清楚,先做一点指导:
// Company model
public function users()
{
return $this->belongsToMany('User')->withTimestamps();
}
// now you can do this:
$company = Company::find($someId);
$company->users;
// which does behind the scenes:
$company->users()->get();
// thus returned Collection
// Alert model
public function location()
{
return $this->hasOne('Location');
}
// calling relation:
$alert = Alert::find($id);
$alert->location; // single model because it does the same as:
$alert->location()->first();
话虽这么说,你可以访问这样的相关模型:
$company->users->first()->alerts->first()->location->address_1;
// and for your needs use of course loops:
// don't call it $alerts as it returns company with some relations
$company = Company::with('users.alerts.location')
->where('id', '=', $company_id)
->first(); // use first not get for the reason I mentioned above
@foreach ($company->users as $user)
@foreach ($user->alerts as $alert)
{{ $alert->location->address_1 }}
...
@endforeach
@endforeach
破坏警报:
// User model
// additional relation for ease of use
public function deletedAlerts()
{
return $this->hasMany('Alert')->onlyTrashed();
}
// only change in the call is replacing alerts with deletedAlerts:
$company = Company::with('users.deletedAlerts.location')
->where('id', '=', $company_id)
->first();
@foreach ($company->users as $user)
@foreach ($user->deletedAlerts as $alert)
{{ $alert->location->address_1 }}
...
@endforeach
@endforeach
答案 1 :(得分:0)
作为日志,因为您的模型具有正确的关系方法,我认为您的查询中缺少的所有内容(因此对象错误)都是第一个()。像这样:
@foreach($alerts as $alert)
<td>{{$alert->users->alerts->first()->location()->address_1}}</td>
@endforeach
答案 2 :(得分:0)
老实说,您不希望控制器中的数据库调用,但在模型中保持对MVC范例的忠诚。我试图绕过这个。我认为你可以将这个重构为关系,并在foreach循环中调用所有内容。
@foreach($user->company()->users as $company_user)
<tr>
<td>
{{ $company_user->username }}
</td>
<td>
@foreach($company_user->alerts() as $alert)
{{ $alert->message }} - {{ $alert->location()->name }}
@endforeach
</td>
</tr>
@endforeach
通过这种设置和正确的关系,这应该可行。这是一个复杂的结构。缺陷是警报的数量可能是可变的(可以是0或更多)?所以你必须在一个<td>
中完成这项工作。希望你能完成它!如果它成功或进展,请告诉我们!
答案 3 :(得分:0)
它不起作用,因为$alert->users
是一个集合,而每个$user
都有$alerts
,这也是另一个集合,并且您正在尝试使用该集合中的属性,在这种情况下,您需要循环所有警报:
<击> @foreach($ alert as $ alert) @foreach($ alert-&gt; users-&gt;提醒为$ alert1) {{$ alert1-&gt; location-&gt; address_1}} @endforeach @endforeach 击>
实际上,$alert->users
是一个集合所以:
@foreach($alerts as $alert)
@foreach($alert->users as $user)
@foreach($user->alerts as $anAlert)
{{ $anAlert->location->address_1 }}
@endforeach
@endforeach
@endforeach
好吧,让我们重写整个事情:
$companies = Company::with('users.alerts.location')
->where('id', '=', $company_id)
->get();
现在,您拥有Company
个users (collection)
模型集合,每个users
都有另一个Alert
集合,因此有多个用户和多个警报,然后每个Alert
有一个Location
,所以:
@foreach($companies as $company)
// Each User belongs to multiple company, so multiple users here
@foreach($company->users as $user)
// Each User has multiple alerts
@foreach($user->alerts as $anAlert)
// Each location belongs to one alert
{{ $anAlert->location->address_1 }}
@endforeach
@endforeach
@endforeach