したがって、Laravelフレームワークから次のエラーを受け取りますが、このフレームワークがこのエラーを生成している理由を見つけることができませんでした。
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'participants' (SQL: select `participants`.*, `participants`.`message_id` as `pivot_message_id`, `participants`.`user_id` as `pivot_user_id`, `participants`.`created_at` as `pivot_created_at`, `participants`.`updated_at` as `pivot_updated_at` from `participants` inner join `participants` on `participants`.`id` = `participants`.`user_id` where `participants`.`deleted_at` is null and `participants`.`message_id` in (2))
メッセージと参加者の関係は次のようになります。
public function participants()
{
return $this->belongsToMany('Namespace\Modules\Email\Models\Participant', 'participants', 'message_id', 'user_id')->withTimestamps();
}
そして私はそれを次のように呼び出そうとしています:
public function getAllMessages()
{
return Message::with('user')->with('participants')->get();
}
このエラーが発生するのはなぜですか?どうしたの?
編集:完全モデルを含む
メッセージ
class Message extends Eloquent
{
use PublishedTrait;
use SoftDeletingTrait;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'messages';
/**
* The attributes that can be set with Mass Assignment.
*
* @var array
*/
protected $fillable = ['subject', 'user_id', 'body', 'status'];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* Validation rules.
*
* @var array
*/
protected $rules = [
'subject' => 'required|max:255',
'body' => 'required',
];
/**
* User relationship
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(Config::get('email.user_model'));
}
public function assets()
{
return $this->belongsToMany('Namespace\Modules\Assets\Models\Asset', 'message_assets');
}
/**
* Participants relationship
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participants()
{
return $this->belongsToMany('Namespace\Modules\Email\Models\Participant', 'participants', 'message_id', 'user_id')->withTimestamps();
}
/**
* Recipients of this message
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function recipients()
{
return $this->participants()->where('user_id', '!=', $this->user_id);
}
/**
* Returns the latest message from a thread
*
* @return Namespace\Modules\Email\Models\Message
*/
public function getLatestMessageAttribute()
{
return $this->messages()->latest()->first();
}
/**
* Returns threads that the user is associated with
* @param $query
* @param $userId
* @return mixed
*/
public function scopeForUser($query, $userId)
{
return $query->join('participants', 'messages.id', '=', 'participants.message_id')
->where('participants.user_id', $userId)
->where('participants.deleted_at', null)
->select('messages.*');
}
/**
* Returns threads that the user is associated with
* @param $query
* @param $userId
* @return mixed
*/
public function scopeForUserWithDeleted($query, $userId)
{
return $query->join('participants', 'messages.id', '=', 'participants.message_id')
->where('participants.user_id', $userId)
->select('messages.*');
}
/**
* Returns messages that the user has sent
* @param $query
* @param $userId
* @return mixed
*/
public function scopeByUser($query, $userId)
{
return $query->where('user_id', $userId);
}
/**
* Returns threads with new messages that the user is associated with
* @param $query
* @param $userId
* @return mixed
*/
public function scopeForUserWithNewMessages($query, $userId)
{
return $query->join('participants', 'messages.id', '=', 'participants.message_id')
->where('participants.user_id', $userId)
->whereNull('participants.deleted_at')
->where(function ($query) {
$query->where('messages.updated_at', '>', $this->getConnection()->raw($this->getConnection()->getTablePrefix() . 'participants.last_read'))
->orWhereNull('participants.last_read');
})
->select('messages.*');
}
}
参加者
class Participant extends Eloquent
{
use SoftDeletingTrait;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'participants';
/**
* The attributes that can be set with Mass Assignment.
*
* @var array
*/
protected $fillable = ['message_id', 'user_id', 'last_read'];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'deleted_at', 'last_read'];
/**
* Thread relationship
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function message()
{
return $this->hasMany('Namespace\Modules\Email\Models\Message');
}
/**
* User relationship
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(Config::get('email.user_model'));
}
}
Larachatの公式Slackから回答:
これが機能するための関係にピボットテーブルがありません。 participants
メソッドの2番目の引数は、使用するピボットテーブルです。
public function participants()
{
return $this->belongsToMany('Namespace\Modules\Email\Models\Participant', 'PIVOT', 'message_id', 'user_id')->withTimestamps();
}
したがって、関係のテーブルの1つであるため、ピボットとして参加者を使用することはできません。message_participant
ピボットテーブルが必要です。
あなたのエラーは
...from `participants` inner join `participants` ...
次のように、各参照にエイリアスを提供する必要があります
...from `participants` p1 inner join `participants` p2 ...
次に、正しい場所でp1
およびp2
を使用します。たとえば、
...on p1.`id` = p2.`user_id` ...
(どちらがp1
で、どちらがp2
であるかを推測しています。その決定を行う必要があります)
後でこのエラーが発生した人のためにこの質問に答えます。
テーブルレコードから判断すると、participants table
はusers
とmessages
の間のpivot table
のようです。ピボットテーブルを参照しているため、データベースが正しく動作していません。
これを行う正しい方法は、users
モデルにあります。
public function messages(){
return $this->belongsToMany(Message::class, 'participants', 'user_id', 'message_id')->withPivot('last_read');
}
messages
モデル:
public function users(){
return $this->belongsToMany(User::class, 'participants', 'message_id', 'user_id')->withPivot('last_read');
}
そうすれば、ユーザーからのメッセージを呼び出すときに、次のように使用できます。
$messages = $user->messages()->get();
そして、ユーザーにメッセージを確認するとき、
$user = $message->users()->get()
そして最後に読んだ
$last_read = $message->pivot->last_read;