Laravel 9来自同一表的两个外键



我有两个表,银行和转账。我试图显示转账表,显示两个银行账户之间的资金转移。如果我不使用任何关系,那么表将显示相应的id,这意味着它工作正常。当我想显示相应的银行账户名称时,问题就出现了。我得到一个错误异常:试图读取属性"accountName"int。

输入图片描述

谁来看看:

这是我目前拥有的:**我的银行模式* *

class Bank extends Model
{
use HasFactory;
protected $fillable = [
'accountName',
'bankName',
'currencyCode',
'accountNumber',
'balance',
'contact',
'address',
'created_by',
];
}

My Transfer Model

class Transfer extends Model
{
use HasFactory;
protected $fillable = [
'fromAccount',
'toAccount',
'amount',
'rate',
'date',
'reference',
'description',
'created_by',
];
public function fromAccount()
{
return $this->belongsTo(Bank::class, 'fromAccount');
}
public function toAccount()
{
return $this->belongsTo(Bank::class, 'toAccount');
}
}

**My Transfers迁移* *

public function up()
{
Schema::create('transfers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('fromAccount');
$table->unsignedBigInteger('toAccount');
$table->float('amount', 15, 4);
$table->double('rate', 15, 8);
$table->date('date');
$table->string('reference');
$table->text('description')->nullable();
$table->integer('created_by')->default('0');
$table->timestamps();
$table->foreign('fromAccount')->references('id')->on('banks');
$table->foreign('toAccount')->references('id')->on('banks');
});
}

**我的索引函数在TransferController* *

public function index()
{
$transfers = Transfer::with('fromAccount', 'toAccount')->get();
return view('backend.pages.transfers.index', compact('transfers'));
}

**我的视图刀片文件* *

@foreach ($transfers as $transfer)
<tr>
<td class="fw-semibold">{{ $transfer->date }}</td>
<td>{{ $transfer->fromAccount->accountName }}</td>
<td>{{ $transfer->toAccount->accountName }}</td>
</tr>
@endforeach

在不使用数据库约定进行命名时,这是一个非常常见的问题。在您的示例中,您已经将迁移中的外键定义为:

Schema::create('transfers', function (Blueprint $table) {
$table->unsignedBigInteger('fromAccount');
$table->unsignedBigInteger('toAccount');
// ...
$table->foreign('fromAccount')->references('id')->on('banks');
$table->foreign('toAccount')->references('id')->on('banks');
});

这很好,但是惯例建议这些应该是from_account_idto_account_id(或类似的)。同样,这些都是"约定",而不是强制执行的规则。

问题是你用相同的名字定义了关系:

public function fromAccount() {
return $this->belongsTo(Bank::class, 'fromAccount');
}
public function toAccount() {
return $this->belongsTo(Bank::class, 'toAccount');
}

由于操作的顺序,当你调用$transfer->toAccount(或->fromAccount)时,你将得到integer。您正确地期望它是一个关系,如$transfer->toAccount->accountName,但您最终调用1->accountName(1id)之类的东西,这是无效的。

要处理这个问题,只需要为列和关系使用唯一的名称。为了符合惯例,我建议如下:

Schema::create('transfers', function (Blueprint $table) {
$table->unsignedBigInteger('from_account_id');
$table->unsignedBigInteger('to_account_id');
// ...
$table->foreign('from_account_id')->references('id')->on('banks');
$table->foreign('to_account_id')->references('id')->on('banks');
});

然后在你的模型中:

public function fromAccount() {
return $this->belongsTo(Bank::class, 'from_account_id');
}
public function toAccount() {
return $this->belongsTo(Bank::class, 'to_account_id');
}
现在,你的代码应该可以工作了:
@foreach ($transfers as $transfer)
<tr>
<td class="fw-semibold">{{ $transfer->date }}</td>
<td>{{ $transfer->fromAccount->accountName }}</td>
<td>{{ $transfer->toAccount->accountName }}</td>
</tr>
@endforeach

如果你需要引用id,你可以调用$transfer->from_account_id$transfer->to_account_id,这样你的代码就不再"模棱两可"了。

相关内容

  • 没有找到相关文章

最新更新