从 blade 视图中的第二个 table 关系中提取数据的正确方法是什么

What is the correct way to extract data from second table relationship in blade view

在我的 route.php 中,我定义了组路由资源:

Route::group(['middleware' => 'role:admin|staff|retailer|customer|spy'],     
function()
{
  Route::resource('profiles', 'ProfileController');
});

我的 User.php 模型包含这种关系

public function address ()
{
  return $this->hasOne('App\Address', 'user_id');
}

我的 Address.php 模型包含这种关系

public function user ()
{
    return $this->belongsTo('App\User');
}

在我的 ProfileController.php 中,我有一个名为 edit() 的 REST 方法,它发送 $user 变量以查看 blade

public function edit($id)
{
   $user = Auth::user();
   return view('profiles.edit')->with('user',$user);
}

事情是这样的:这是我的 /view/profiles/edit.blade.php。只是 2 个编辑字段的示例:

{!! Form::model($user, [
        'method' => 'PATCH',
        'route' => ['profiles.update', $user->id]
    ]) !!}
   <div class="form-group">
        {!! Form::label('lblfirst_name', 'First Name:', ['class' => 'control-label']) !!}
        {!! Form::text('first_name', null, ['class' => 'form-control']) !!}
    </div>

    <div class="form-group">
        {!! Form::label('lbladdress_line1', 'Address line 1:', ['class' => 'control-label']) !!}
        {!! Form::text('address_line1', $user->address->address_line1, ['class' => 'form-control']) !!}
    </div>


{!! Form::close() !!}

注意

$user->address->address_line1

目前这就是我从地址 table 中提取数据的方式,使用这种方式,我发现此表单执行了 1 个额外的 sql 查询:

select * from addresses where addresses.user_id = '1' and addresses.user_id is not null limit 1

我的问题是,有更好的方法吗?我的意思是不做额外的查询,比如我如何提取上面的名字字段。

当您调用 Auth::user() 时,它会:

vendor/laravel/src/Illuminate/Auth/EloquentUserProvider.php:

/**
 * Retrieve a user by their unique identifier.
 *
 * @param  mixed  $identifier
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
public function retrieveById($identifier)
{
    return $this->createModel()->newQuery()->find($identifier);
}

它获取用户模型并执行 ->find($id),因此即使您更改 find() 函数的行为,您也必须发送第二个请求来检索相关数据。 Eloquent 就是这样。

你唯一能做的就是缓存第二个查询:

$user = Auth::user();
$address = Cache::remember('users::'.$user->id.'::address', 10, function() use ($user) {
    return Address::where('user_id', $user->id)->first();
});
return view('profiles.edit', compact('user', 'address'));