【问题标题】:SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias on relationshipSQLSTATE [42000]:语法错误或访问冲突:1066 Not unique table/alias on relationship
【发布时间】:2015-09-12 14:32:22
【问题描述】:

所以,我从 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'));
    }
}

【问题讨论】:

    标签: mysql laravel eloquent laravel-4 relationship


    【解决方案1】:

    为很久以后遇到此错误的任何人回答此问题。

    从您的表记录来看,participants table 似乎是usersmessages 之间的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;
    

    【讨论】:

      【解决方案2】:

      通过 Larachat 官方 Slack 回答:

      此关系缺少数据透视表才能正常工作。 participants 方法中的第二个参数是要使用的数据透视表:

      public function participants()
      {
          return $this->belongsToMany('Namespace\Modules\Email\Models\Participant', 'PIVOT', 'message_id', 'user_id')->withTimestamps();
      }
      

      因此,您不能使用参与者作为数据透视表,因为它是关系中的表之一,您需要一个message_participant 数据透视表。

      【讨论】:

      • 注意第一个参数是你想要的模型的名称,而不是数据透视表/模型的名称。混合会引发类似的错误。
      【解决方案3】:

      你的错误是

      ...from `participants` inner join `participants` ...
      

      您需要为每个引用提供别名,如

      ...from `participants` p1 inner join `participants` p2 ...
      

      然后在正确的地方使用p1p2,例如

      ...on p1.`id` = p2.`user_id` ...
      

      (我猜哪个是p1,哪个是p2;你必须做出决定)

      【讨论】:

      • 如何用雄辩的语法定义这个别名?
      • 这是一个关于 laravel 中 eloquent 关系的问题,而不是如何进行 sql 连接和别名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 2023-04-01
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多