如何通过模型关系从三个相关表中获取数据?

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

对于BelongsToHasOne 关系,请使用单名词:

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-&gt;user-&gt;employee-&gt;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,
       ,
     ],
   
*/

【讨论】:

以上是关于如何通过模型关系从三个相关表中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 从关系表中获取数据

Laravel 雄辩模型如何从关系表中获取数据

SQL Server:如何从只有 ID 的联结表中获取数据?

如何使用 laravel 6 使用两个模型之间的关系从第一个表中获取 field_name?

Django使用“通过”关系表从模型中获取所有相关对象

如何从 Prisma 中的 MySql 关系表中获取数据