![](/img/trans.png)
[英]Laravel models, relationships how to make a innjoin query using Eloquent?
[英]How to make Compact code Laravel 5 Eloquent Relationships
我的控制器上有以下不简单的代码:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\UserDetail;
use App\UserSex;
use App\Province;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class UserController extends Controller {
...
public function show($id) {
//
$User = User::find($id);
$UserDetail = User::find($id)->UserDetail;
$UserSex = User::find($id)->UserSex;
$Province = User::find($id)->Province;
return view('users.show', compact('UserDetail', 'User', 'UserSex', 'Province'));
}
...
此代码在我的模型之一上:
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
...
protected $hidden = ['password', 'remember_token'];
public $timestamps = false;
public function UserDetail() {
return $this->hasOne('App\UserDetail', 'userDetail_id');
}
public function UserSex() {
return $this->hasOne('App\UserSex', 'sex_id');
}
public function Province() {
return $this->hasOne('App\Province', 'province_id');
}
...
并将此代码显示在视图上 :
<div class="form-group">
<label for="isbn" class="col-sm-2 control-label">User Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="isbn" placeholder="{!! $User->username !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="firstName" placeholder="{!! $UserDetail->firstName !!} {!! $UserDetail->lastName !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">Sex</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="sex" placeholder="{!! $UserSex->gender !!}" readonly>
</div>
</div>
如您在控制器中看到的,我调用模型中的每个函数( return view('users.show',compact('UserDetail','User','UserSex','Province')); )以显示表之间的数据在雄辩的人际关系中 。
我做这样的代码没有错误,并且运行良好。
我的问题是,我做对了吗(基于Laravel 5)?
因为我认为这种方法并不简单 , 所以如果以后做很多表,它也不紧凑 。 我仍然没有探索所有的laravel功能。 也许你们中的一些人可以帮助我做对。
首先,您的方法和变量名应为驼峰式,请参见http://www.php-fig.org/psr/psr-1/#4-2-properties和http://www.php-fig.org/ PSR / PSR-2 /#4-3的方法
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\UserDetail;
use App\UserSex;
use App\Province;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class UserController extends Controller {
...
public function show($id) {
//
$user = User::find($id);
$userDetail = User::find($id)->userDetail;
$userSex = User::find($id)->userSex;
$province = User::find($id)->province;
return view('users.show', get_defined_vars());
}
您也可以使用get_defined_vars 。 这会将您所有已定义的变量放入范围,并将其传递给视图。
还要将方法名称更改为驼峰式
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
...
protected $hidden = ['password', 'remember_token'];
public $timestamps = false;
public function userDetail() {
return $this->hasOne('App\UserDetail', 'userDetail_id');
}
public function userSex() {
return $this->hasOne('App\UserSex', 'sex_id');
}
public function province() {
return $this->hasOne('App\Province', 'province_id');
}
在视图中更改变量
<div class="form-group">
<label for="isbn" class="col-sm-2 control-label">User Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="isbn" placeholder="{!! $user->username !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="firstName" placeholder="{!! $userDetail->firstName !!} {!! $userDetail->lastName !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">Sex</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="sex" placeholder="{!! $userSex->gender !!}" readonly>
</div>
</div>
另外,请尝试使用快速加载,因为它可以解决查询n + 1问题http://laravel.com/docs/5.1/eloquent-relationships#eager-loading并限制您的选择
我宁愿在您的控制器中为$user
变量编写此代码
$user = User::with(['userDetail' => function($q){
$q->select(['id', 'firstName', 'lastName']);
}, 'userSex' => function($q){
$q->select(['id', 'gender']);
}])->findOrFail($id);
在你看来
<div class="form-group">
<label for="isbn" class="col-sm-2 control-label">User Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="isbn" placeholder="{!! $user->username !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="firstName" placeholder="{!! $user->userDetail->firstName !!} {!! $user->userDetail->lastName !!}" readonly>
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">Sex</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="sex" placeholder="{!! $user->userSex->gender !!}" readonly>
</div>
</div>
始终限制选择和不必要的连接,因为这可能会很昂贵
尝试使用Eager Loading一起启动模型,以便控制器看起来像这样:
$user=User::find($id)->with('UserDetail')->with('UserSex')->with('Province');
return view('users.show')->with('user',$user);
它将大大提高应用程序的性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.