Eloquent 具有非默认主键的关系(belongsTo、hasMany)
Eloquent relationships (belongsTo, hasMany) with non-default primaryKey
我是关系数据库的新手,目前我是 运行 一个本地 sqlite 数据库,只是想建立一个 pivot/relational 数据库,我可以在其中获取参与者的消息列表,方法是使用他们的 phone 号码作为主键。没有登录,登录基本上是由用户通过从他们的 phone 发送短信到应用程序来完成的,所以我不能在我的估计中使用典型的 'id' 列。在我的数据库中 participant_id 也可能是 phone 号。我不确定我做错了什么。
在我的控制器中,当我访问预定义的路线时,我只是尝试使用此代码对结果进行 DD:
public function showMessages()
{
$participant_id = "+5555555";
//$activeParticipant = Participant::where('participant_id', $participant_id);
$activeParticipant = Participant::find($participant_id);
$messages = $activeParticipant->messages;
dd($messages);
//$messages = Participant::find($participant_id)->messages;
}
我收到以下错误:
SQLSTATE[HY000]: General error: 1 no such column: participants.id (SQL: select * from "participants" where "participants"."id" = +5555555 limit 1)
尽管存在这个错误,但我很确定我有问题,我只是不明白在下面的代码中该做什么...如果有人能帮助我解释一下,我将不胜感激。
这是我的模型和数据库迁移:
参与者迁移:
class CreateParticipantsTable extends Migration
{
protected $primaryKey = 'participant_id';
protected $incrementing = false;
public function up()
{
Schema::create('participants', function (Blueprint $table) {
$table->string('participant_id')->unique()->primary();
$table->date('appointment_date')->nullable();
$table->boolean('subscribed');
$table->timestamps();
});
}
参与者模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Participant extends Model
{
protected $table = 'participants';
protected $fillable = ['participant_id', 'appointment_date', 'subscribed'];
public function messages()
{
return $this->hasMany(Message::class);
// return $this->hasMany('App\Message', 'message_id', 'participant_id');
}
public function notifications()
{
return $this->hasMany(Notification::class);
}
}
消息迁移:
class CreateMessagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned();
$table->string('phoneNumber')->nullable();
$table->string('message_content')->nullable();
$table->string('mediaSID')->index()->nullable();
$table->string('messageSID')->index()->nullable();
$table->string('mediaURL')->index()->nullable();
$table->binary('media')->nullable();
$table->string('filename')->index()->nullable();
$table->string('MIMEType')->nullable();
$table->timestamps();
$table->foreign('message_id')->references('participant_id')->on('participants')->onDelete('cascade');
});
}
消息模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $table = 'messages';
protected $hidden = 'media';
protected $fillable = ['message_id', 'phoneNumber', 'message_content', 'mediaSID', 'messageSID', 'mediaURL', 'media', 'filename', 'MIMEType'];
public function participant()
{
return $this->belongsTo(Participant::class);
}
}
Laravel 尝试从名称中猜测模型的主键。所以,调用时:
$activeParticipant = Participant::find($participant_id);
Laravel 正在调用 SELECT * FROM participants WHERE participants.id = ? ...
,它返回 participants.id
的问题,因为该列不存在。
由于您使用的是自定义主键,因此需要对其进行定义。在您的 Participant
模型上,在 class 声明附近添加以下内容:
protected $primaryKey = "participant_id";
设置后,默认查询逻辑将调整为SELECT * FROM participants WHERE participants.participant_id = ? ...
,一切都应该是金色的。
注意:您可能对 Participant
和其他模特之间的任何关系有类似的问题。 Laravel 再次尝试猜测用于 ->hasMany()
、->belongsTo()
等的列,因此仔细检查 Documentation for Relationships,特别是这些方法可用的附加参数。
编辑:
//$activeParticipant = Participant::where('participant_id', $participant_id);
如果您在其末尾添加 ->first()
以实际执行查询,将会有效。没有 Closure
(->first()
、->get()
、->paginate()
等),您有一个 Builder
实例,而不是实际的数据库结果(null
, Collection
或 Participant
)
我是关系数据库的新手,目前我是 运行 一个本地 sqlite 数据库,只是想建立一个 pivot/relational 数据库,我可以在其中获取参与者的消息列表,方法是使用他们的 phone 号码作为主键。没有登录,登录基本上是由用户通过从他们的 phone 发送短信到应用程序来完成的,所以我不能在我的估计中使用典型的 'id' 列。在我的数据库中 participant_id 也可能是 phone 号。我不确定我做错了什么。
在我的控制器中,当我访问预定义的路线时,我只是尝试使用此代码对结果进行 DD:
public function showMessages()
{
$participant_id = "+5555555";
//$activeParticipant = Participant::where('participant_id', $participant_id);
$activeParticipant = Participant::find($participant_id);
$messages = $activeParticipant->messages;
dd($messages);
//$messages = Participant::find($participant_id)->messages;
}
我收到以下错误:
SQLSTATE[HY000]: General error: 1 no such column: participants.id (SQL: select * from "participants" where "participants"."id" = +5555555 limit 1)
尽管存在这个错误,但我很确定我有问题,我只是不明白在下面的代码中该做什么...如果有人能帮助我解释一下,我将不胜感激。
这是我的模型和数据库迁移: 参与者迁移:
class CreateParticipantsTable extends Migration
{
protected $primaryKey = 'participant_id';
protected $incrementing = false;
public function up()
{
Schema::create('participants', function (Blueprint $table) {
$table->string('participant_id')->unique()->primary();
$table->date('appointment_date')->nullable();
$table->boolean('subscribed');
$table->timestamps();
});
}
参与者模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Participant extends Model
{
protected $table = 'participants';
protected $fillable = ['participant_id', 'appointment_date', 'subscribed'];
public function messages()
{
return $this->hasMany(Message::class);
// return $this->hasMany('App\Message', 'message_id', 'participant_id');
}
public function notifications()
{
return $this->hasMany(Notification::class);
}
}
消息迁移:
class CreateMessagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned();
$table->string('phoneNumber')->nullable();
$table->string('message_content')->nullable();
$table->string('mediaSID')->index()->nullable();
$table->string('messageSID')->index()->nullable();
$table->string('mediaURL')->index()->nullable();
$table->binary('media')->nullable();
$table->string('filename')->index()->nullable();
$table->string('MIMEType')->nullable();
$table->timestamps();
$table->foreign('message_id')->references('participant_id')->on('participants')->onDelete('cascade');
});
}
消息模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $table = 'messages';
protected $hidden = 'media';
protected $fillable = ['message_id', 'phoneNumber', 'message_content', 'mediaSID', 'messageSID', 'mediaURL', 'media', 'filename', 'MIMEType'];
public function participant()
{
return $this->belongsTo(Participant::class);
}
}
Laravel 尝试从名称中猜测模型的主键。所以,调用时:
$activeParticipant = Participant::find($participant_id);
Laravel 正在调用 SELECT * FROM participants WHERE participants.id = ? ...
,它返回 participants.id
的问题,因为该列不存在。
由于您使用的是自定义主键,因此需要对其进行定义。在您的 Participant
模型上,在 class 声明附近添加以下内容:
protected $primaryKey = "participant_id";
设置后,默认查询逻辑将调整为SELECT * FROM participants WHERE participants.participant_id = ? ...
,一切都应该是金色的。
注意:您可能对 Participant
和其他模特之间的任何关系有类似的问题。 Laravel 再次尝试猜测用于 ->hasMany()
、->belongsTo()
等的列,因此仔细检查 Documentation for Relationships,特别是这些方法可用的附加参数。
编辑:
//$activeParticipant = Participant::where('participant_id', $participant_id);
如果您在其末尾添加 ->first()
以实际执行查询,将会有效。没有 Closure
(->first()
、->get()
、->paginate()
等),您有一个 Builder
实例,而不是实际的数据库结果(null
, Collection
或 Participant
)