【问题标题】:Laravel changing primary key from URLs results in errorLaravel 从 URL 更改主键会导致错误
【发布时间】:2021-07-12 10:08:48
【问题描述】:

我将帖子表上的 primary_key 从“id”更改为“slug”列。这样我的帖子可以通过 /posts/slug 而不是 /posts/id 访问。这给我带来了很多问题,其中一个是我无法解决的:我在每个帖子上都有一个类似的功能,它曾经发布到 /posts/id/like。我尝试将其更改为 /posts/slug/like 导致以下错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'likes.post_slug' in 'where clause' (SQL: select * from `likes` where `likes`.`post_slug` = test1 and `likes`.`post_slug` is not null and (`user_id` = 1) limit 1)

问题是:我没有 likes.post_slug 列。此外,我从未指示我的代码检查“likes.post_slug”列。在它可能发布到确实存在的“likes.post_id”之前。所以显然 Laravel 正在那里做一些事情,我现在不知道如何应用到我的案例中。我想让它工作,这样我就可以发布到/posts/slug/like。 在下面我发布我的代码,希望有人可以识别出什么是关闭的。 路线:

Route::post('/posts/{post}/like', [PostsLikeController::class, "store"]);
Route::delete('/posts/{post}/like', [PostsLikeController::class, "destroy"]);

PostsLikeController:

class PostsLikeController extends Controller
{
    public function store(Post $post)
    {
        $post->like(auth()->user());

        return back();
    }

    public function destroy(Post $post)
    {
        $post->dislike(auth()->user());

        return back();
    }
}

我喜欢的方法:

trait Likable
{
public function scopeWithLikes(Builder $query)
{
    $query->leftJoinSub(
        'select post_id, sum(liked) likes, sum(!liked) dislikes from likes group by post_id',
        'likes',
        'likes.post_id',
        'id'
    );
}

public function isLikedBy(User $user)
{
    return (bool) $user->likes
        ->where('post_id', $this->id)
        ->where('liked', true)
        ->count();
}

public function isDislikedBy(User $user)
{
    return (bool) $user->likes
        ->where('post_id', $this->id)
        ->where('liked', false)
        ->count();
}

public function likes()
{
    return $this->hasMany(Like::class);
}

public function dislike($user = null)
{
    return $this->like($user, false);
}

public function like($user = null, $liked = true)
{
    $this->likes()->updateOrCreate(
        [
            'user_id' => $user ? $user->id : auth()->id(),
        ],
        [
            'liked' => $liked,
        ]
    );
}

}

Like 类:

class Like extends Model
{
    use HasFactory;
    protected $guarded = [];
}

帖子类:

class Post extends Model
{
    use HasFactory, Likable;
    protected $table = "posts";
    public $primaryKey = "slug";
    public $incrementing = false;
    public $timestamps = true;

    public function user(){
        return $this->belongsTo("App\Models\User");
    }

}

用户类(仅相关方法)

class User extends Authenticatable
{
    public function posts(){
    return $this->hasMany("App\Models\Post");
}

    public function likes()
    {
        return $this->hasMany(Like::class);
    }
}

【问题讨论】:

  • 为什么在工作中你会这样做,除了必须检查所有引用之外,你还必须重写所有查询。你会失去性能
  • @nbk “为什么在工作中你会这样做”是什么意思?做什么?
  • 我的意思是你为什么要更改主键,我描述了你必须付出的努力。更改主键不会有任何好处

标签: php mysql laravel laravel-8


【解决方案1】:

别着急,解决办法其实很简单。

https://laravel.com/docs/8.x/eloquent#primary-keys

您需要做的就是将以下行放入您的App/Models/Post

protected $primaryKey = 'slug';

然后将Likes 表中的数据库列名从post_id 更改为post_slug

免责声明:我不同意 OP 认为这是处理这种情况的最佳方式,我只是想回答他/她的问题。我不建议您使用他/她的代码或我的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2011-08-17
    相关资源
    最近更新 更多