如何通过模型关系从三个相关表中获取数据?
Posted
技术标签:
【中文标题】如何通过模型关系从三个相关表中获取数据?【英文标题】:How to get data from three related table with it's model relationships? 【发布时间】:2021-08-05 04:30:34 【问题描述】:我有三个这样的表:
费用:-
-
expense_id
user_id
用户:-
-
user_id
employee_id
员工:-
-
employee_id
名字
姓氏
我想从expense.user_id = user.user_id
的员工表中获取first_name
和 last_name
,我尝试了类似下面的方法,但我没有得到正确的数据。
费用模式:-
public function users()
return $this->hasOne(User::class,'user_id','user_id');
用户模型:-
public function employee()
return $this->hasOne(Employee::class,'employee_id','user_id');
和员工模型:-
public function users()
return $this->belongsTo(User::class,'employee_id');
我打电话是这样看的:-
<td>$expense->users->employee->first_name ." " . $expense->users->employee->last_name </td>
它显示数据,但不是预期的数据。
我的错误在哪里,应该怎么做? 请帮忙! 谢谢!
【问题讨论】:
【参考方案1】:我建议你用这种方式重新设计你的数据库和关系:
Expense:-
id
user_id
User:-
id
Employee:-
id
user_id
first_name
last_name
对于BelongsTo
和HasOne
关系,请使用单名词:
class Expense extends Model
public function user()
return $this->belongsTo(User::class);
class User extends Model
public function employee()
return $this->hasOne(Employee::class);
class Employee extends Model
public function user()
return $this->belongsTo(User::class);
public function getFullNameAttribute()
return $this->first_name . ' ' . $this->last_name;
最后,您可以像这样访问员工的全名:
$expense->user->employee->full_name;
【讨论】:
我无法编辑我的数据库,因为我从员工中选择了用户,在这里我声明谁可以访问系统 如果这段代码不是根据重新设计的数据库,所以这不起作用,也没有错误,但如果是根据你的建议,我应该另找方法。 @ZiaYamin 我已经添加了另一个答案,请检查。【参考方案2】:class Expense extends Model
public function user()
return $this->belongsTo(User::class);
class User extends Model
public function employee()
return $this->belongsTo(Employee::class);
class Employee extends Model
public function user()
return $this->hasOne(User::class);
public function getFullNameAttribute()
return $this->first_name . ' ' . $this->last_name;
然后访问客户属性:
<td>$expense->user->employee->full_name</td>
【讨论】:
我应该在哪里返回这个return $expense->user->employee->full_name;
@ZiaYamin 在你的 html 中,我已经更新了我的答案。
不带任何数据
@ZiaYamin 啊,我错过了return
方法中的getFullNameAttribute
关键字。我已经更新了我的答案,请再试一次。
我添加了 return 关键字,但注意到改变了【参考方案3】:
我相信你在滥用雄辩的关系。
One To One Relationship.
One To Many Relationship
一对多关系用于定义一个关系 单个模型是一个或多个子模型的父模型。
试试这个吧。
use App\Models\Employee;
use App\Models\Expense;
// User model.
class User extends Authenticatable
use HasFactory, Notifiable;
protected $primaryKey = 'user_id';
protected $table = 'users';
public function employee()
return $this->hasOne(Employee::class, "employee_id", "employee_id");
public function expenses()
return $this->hasMany(Expense::class, "user_id", "user_id");
// Expense model
class Expense extends Model
use HasFactory;
protected $primaryKey = 'expense_id';
public function user()
return $this->belongsTo(User::class, "user_id", "user_id");
// Employee model.
class Employee extends Model
use HasFactory;
protected $primaryKey = 'employee_id';
public function user()
return $this->belongsTo(User::class, "employee_id", "employee_id");
// 'create_users_table' migration.
class CreateUsersTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('users', function (Blueprint $table)
$table->id('user_id');
$table->unsignedBigInteger("employee_id");
$table->timestamps();
$table->foreign("employee_id")
->references("employee_id")
->on("employees")
->onDelete("cascade");
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('users');
// 'create_expenses_table' migration.
class CreateExpensesTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('expenses', function (Blueprint $table)
$table->id('expense_id');
$table->unsignedBigInteger("user_id");
$table->timestamps();
$table->foreign("user_id")
->references("user_id")
->on("users")
->onDelete("cascade");
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('expenses');
// 'create_employees_table' migration.
class CreateEmployeesTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::create('employees', function (Blueprint $table)
$table->id("employee_id");
$table->string("first_name");
$table->string("last_name");
$table->timestamps();
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('employees');
// Sample query 1.
App\Models\Expense::find(1)
->with(
["user" => function($query)
$query->with("employee");
])
->first();
// Sample output 1.
/*
=> App\Models\Expense #4172
expense_id: 1,
user_id: 1,
created_at: null,
updated_at: null,
user: App\Models\User #4322
user_id: 1,
employee_id: 1,
created_at: null,
updated_at: null,
employee: App\Models\Employee #4330
employee_id: 1,
first_name: "john",
last_name: "doe",
created_at: null,
updated_at: null,
,
,
*/
// Sample query 2.
App\Models\Expense::with(
["user" => function($query)
$query->with("employee");
])->get();
// Sample output 2.
/*
=> Illuminate\Database\Eloquent\Collection #4318
all: [
App\Models\Expense #4320
expense_id: 1,
user_id: 1,
created_at: null,
updated_at: null,
user: App\Models\User #3382
user_id: 1,
employee_id: 1,
created_at: null,
updated_at: null,
employee: App\Models\Employee #4335
employee_id: 1,
first_name: "john",
last_name: "doe",
created_at: null,
updated_at: null,
,
,
,
App\Models\Expense #4323
expense_id: 2,
user_id: 1,
created_at: null,
updated_at: null,
user: App\Models\User #3382,
,
],
*/
【讨论】:
以上是关于如何通过模型关系从三个相关表中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server:如何从只有 ID 的联结表中获取数据?