我正在Laravel 9.x中开发一个应用程序,我的应用程序目前包括7个表。每个表都有一个主键,这些主键中的NONE是标准的递增整数id
。对于我的每个模型,我都在模型中添加了一行,指示实际主键是什么,并指示递增为false。我的迁移也正确定义了各自的主键。
我目前正在为我的7个控制器编写index()和show()方法,当我执行index()方法时,发生了一些非常奇怪的事情:主键列中的值与我在DatabaseSeeder中植入的值不同。在一个主键为字符串的表中,index()方法在表的每一行的主键列中显示0。在另一个主键为日期的表中,index()方法在表的每一行的主键列中只显示日期的年份部分。
我发现,使主键列中显示正确值的唯一方法是注解掉模型中的主键定义。
我对这种行为感到非常困惑。有人能告诉我为什么会发生这种情况以及如何解决吗?
这是我迁移的up()方法,其中定义了一个表:
public function up()
{
Schema::create('non_driving_reasons', function (Blueprint $table) {
$table->string('reason_for_not_driving', 50);
$table->primary('reason_for_not_driving', 'reason_for_not_driving_PK');
$table->timestamps();
});
}
以下是植入此表的值的示例:
\App\Models\NonDrivingReasons::factory()->create([
'reason_for_not_driving' => 'Snow Day'
]);
\App\Models\NonDrivingReasons::factory()->create([
'reason_for_not_driving' => 'Professional Development Day'
]);
\App\Models\NonDrivingReasons::factory()->create([
'reason_for_not_driving' => 'School staff on strike'
]);
\App\Models\NonDrivingReasons::factory()->create([
'reason_for_not_driving' => 'School Holiday - Christmas'
]);
这是非驱动原因控制器的index()方法:
public function index() {
return view('nonDrivingReasons.index', [
'nonDrivingReasons' => NonDrivingReasons::paginate(6)
]);
}
这是NonDrivingReasons表的索引刀片:
<x-layout>
<div class="bg-gradient-to-b from-red-500 to-purple-100">
<h1 class="text-3xl text-center text-white font-bold bg-indigo-700">Non-driving Reasons</h1>
<h1 class="pb-5"></h1><!-- spacer beneath title -->
<div class="flex justify-center h-screen" style="display: grid; grid-template-rows: auto auto auto auto; row-gap: 25px; padding: 10px">
<div>
{{-- If there are no non-driving reasons, indicate that to the user. --}}
@if (count($nonDrivingReasons) == 0)
<p>No non-driving reasons found.</p>
@endif
</div>
<div>
<table><thead><tr><th><a href="/nonDrivingReasons/create"><img src="{{asset('icons/green-plus-circle-outline.svg')}}" width="50" alt="add icon"></a></th><th><a href="/nonDrivingReasons/create">Add new non-driving reason</a></th></tr></thead></table>
</div>
{{-- If there are non-driving reasons, display them. --}}
<div>
<table class="border-black border-2 bg-white">
<thead class="border-black border-2 text-white bg-gray-800">
<tr class="content-center">
<th class="border-black border-2 p-2 text-left">Non-Driving Reason</th>
<th class="border-black border-2 p-2">View</th>
<th class="border-black border-2 p-2">Edit</th>
<th class="border-black border-2 p-2">Delete</th></tr>
</thead>
<tbody class="border-black border-2">
@foreach($nonDrivingReasons as $nonDrivingReason)
<tr class="border-black border-2">
<td class="border-black border-2 p-2">{{$nonDrivingReason->reason_for_not_driving}}</td>
<td class="border-black border-2 p-2"><a href="/nonDrivingReasons/show/{{$nonDrivingReason->reason_for_not_driving}}"><img src="{{asset('icons/magenta-details.svg')}}" width="25" alt="view logo"></a></td>
<td class="border-black border-2 p-2"><a href="/nonDrivingReasons/edit/{{$nonDrivingReason->reason_for_not_driving}}"><img src="{{asset('icons/yellow-lead-pencil.svg')}}" width="25" alt="update logo"></a></td>
<td class="border-black border-2 p-2"><a href="/nonDrivingReasons/destroy/{{$nonDrivingReason->reason_for_not_driving}}"><img src="{{asset('icons/red-delete.svg')}}" width="25" alt="delete logo"></a></td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div>
<p class="mt-6 p-4">{{$nonDrivingReasons->links()}}</p>
</div>
</div>
<h1 class="pt-5"> </h1><!-- spacer at bottom of page -->
</div>
</x-layout>
这是非驱动性原因的模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class NonDrivingReasons extends Model
{
use HasFactory;
protected $fillable = ['reason_for_not_driving'];
protected $primaryKey = 'reason_for_not_driving';
public $incrementing = 'false';
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery($query)
{
$keys = $this->getKeyName();
if(!is_array($keys)){
return parent::setKeysForSaveQuery($query);
}
foreach($keys as $keyName){
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}
return $query;
}
/**
* Get the primary key value for a save query.
*
* @param mixed $keyName
* @return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if(is_null($keyName)){
$keyName = $this->getKeyName();
}
if (isset($this->original[$keyName])) {
return $this->original[$keyName];
}
return $this->getAttribute($keyName);
}
}
同样,为了使正确的数据出现在表的Non-Driving Reason中,我需要做的就是在我的模型中注解掉$primaryKey = 'reason_for_not_driving';
,但这不是一个好的解决方案,因为它会导致Controller中的表查询失败,因为Eloquent假设主键必须是id,而id在表中不存在。
1条答案
按热度按时间jw5wzhpr1#
如果定义的主键不是
integer
类型,则必须相应地定义$keyTpye
。有关主键的更多信息,请参阅以下文档:https://laravel.com/docs/9.x/eloquent#primary-keys