如果它至少具有一个User
,我想获得一个Section模型的集合。从文档中的has()
方法可以做到这一点,很棒。检索到的集合中没有users
关系。然而,当我遍历集合时,我可以获得users
的属性。为什么?
class Section extends Model
{
protected $guarded = [];
public function users()
{
return $this->hasMany('App\User');
}
}
class User extends Authenticatable
{
protected $guarded = [];
public function section()
{
return $this->belongsTo('App\Section');
}
}
这是我做的:
$section = Section::where('id' , 1)->has('users')->get();
集合是这个:
Illuminate\Database\Eloquent\Collection {#3025
all: [
App\Section {#3015
id: 1,
class_id: 1,
section_name: "A",
created_at: "2019-12-14 18:26:01",
updated_at: "2019-12-14 18:26:01",
},
],
}
现在奇怪的是,当我执行以下操作时,即使在集合中不存在users
关系,它也提供了用户的属性。
为什么?
@foreach ($section as $section)
@foreach ($section->users as $student)
<p>{{$student->name}}</p>
@endforeach
@endforeach
solomon
uche
kene
答案 0 :(得分:0)
好的,现在我明白了你的问题。
has
方法并不意味着它将包含User
。这意味着将返回至少有一个用户的所有sections
。我认为有Section
id === 1的用户。因此,在带有has
或不带有with
的代码中,它没有任何区别。
如果要显式加载关系,则应使用Section::where('id' , 1)->with('users')->get();
blade
。然后您应该在每个部分下收集用户。
第二
您仍然可以访问lazy loading
文件中的用户属性的原因是由于BeautifulSoup
。即使原始数据库查询和结果中没有包含它,但是当您尝试访问它时,laravel仍会尝试为您获取这些内容。这可能会导致N + 1问题。
答案 1 :(得分:0)
看起来像您的第一个回声:
$section = Section::where('id' , 1)->has('users')->get();
仅打印它拥有用户的部分,但您并不是要明确地说给我用户。
在下一个循环中,您将循环遍历视图中的每个部分,并具体说来循环关系。此行可见:@foreach ($section->users as $student)
我在这里阅读文档:https://laravel.com/docs/6.x/eloquent-relationships#querying-relations
在打印部分时的第一次回声中,您可以像这样获得用户:echo $section-> users()
答案 2 :(得分:0)
这就是Laravel的工作方式。
在您的情况下$model->{relationship}
,访问$section->users
是一个魔术函数,它检查您是否已通过类似Section::with('users')
的方式显式加载了该关系,如果没有,则进行了加载然后。
在运行users
时没有看到dd($section)
的原因是您没有显式加载该关系,但这并不意味着该关系不可用。如果您在初始查询中包含with('users')
,则会看到以下内容:
$section = Section::where('id' , 1)->has('users')->with('users')->get();
App\Section {#3015
id: 1,
class_id: 1,
section_name: "A",
created_at: "2019-12-14 18:26:01",
updated_at: "2019-12-14 18:26:01",
users: [
0 => App\User {#3016}
id: ...
name: ...
]
},
// Or similar
基本上,您没有加载该关系,因此在使用dd($section)
时看不到该关系,但是由于Laravel的魔术方法,该关系在PHP中仍然可用。
我还应该注意,对查询使用正确的变量命名和闭包(->get()
,->first()
等)。
$section
时, ->get()
是一个不好的名字,因为您将从数据库中获取多个记录。要么使用$sections
,要么将闭包更改为->first()
,如果使用foreach()
,则不要使用->first()
。