【问题标题】:Limit user posts in a single record将用户帖子限制在一条记录中
【发布时间】:2016-11-22 23:56:07
【问题描述】:

我的应用程序中有这种情况,我必须限制用户可以编写的帖子。例如,我有一个名为 Edition 的表来存储版本数据和一个 Article 表来存储文章数据。版本表和文章表是一对多的关系(一个版本有很多文章)。现在,我有一个用户表来存储用户数据,并且该表与文章表具有一对多的关系(一个用户有许多文章)。切入正题,我想制定一个规则,用户在每个版本中只能有一篇文章。假设有一个名为“日本食品”的版本记录,在这个版本记录中用户可以发布他们的文章但只有一篇文章。已经在此“日本料理”版发表文章的用户只能在尚未发布任何文章的其他版本记录中发布新文章。现在我的问题是,如何在 Laravel 中制定这样的规则?特别是 Laravel 5.3。我已经创建了我的迁移和模型,下面是代码(以防有必要帮助您回答我的问题)。

版本表:

public function up() {
        Schema::create('edition', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->integer('volume');
            $table->text('cover')->nullable();
            $table->integer('number');
            $table->timestamps();
        });
        Schema::table('article', function(Blueprint $table) {
            $table->foreign('id_edition')->references('id')->on('edition')->onDelete('cascade')->onUpdate('cascade');
        });
    }
    public function down() {
        Schema::table('article', function(Blueprint $table) {
            $table->dropForeign('article_id_edition_foreign');
        });

        Schema::drop('edition');
    }

文章表:

public function up() {
        Schema::create('article', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title', 255);
            $table->text('content');
            $table->text('file');
            $table->integer('id_edition')->unsigned();
            $table->integer('user_id')->unsigned();
            $table->string('articleslug');
            $table->enum('publish', ['yes', 'no']);
            $table->timestamps();
        });
        Schema::table('article', function(Blueprint $table) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
        });
    }
    public function down() {
        Schema::table('article', function(Blueprint $table) {
            $table->dropForeign('article_user_id_foreign');
        });
        Schema::drop('article');
    }

用户表:

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('username')->unique();
            $table->string('userslug');
            $table->string('nameslug');
            $table->string('email')->unique();
            $table->string('phone')->nullable();
            $table->string('address')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->enum('level', ['admin', 'author']);
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::drop('users');
    }

我的控制器:

public function storeArticle(ArticleRequest $request) {
        $input = $request->all();
        $input['user_id'] = Auth::id();
        $idi = $request->id;
        $id_edition = Edition::findOrfail($idi);
        $user = Auth::user();
        if ($this->userPolicy->userHasArticle($user, $id_edition)) {
            //Input PDF
            if ($request->hasFile('file')) {
                $input['file'] = $this->uploadPDF($request);
            }
            //Insert article datas
            $article = Edition::findOrFail($idi)->article()->create($input);
            $article->user()->attach($request->input('penulis'));
            return redirect()->route('edition', ['id' => $idi]);
        } else {
            return 'Error! You already posted your article in this edition, please pick another edition instead';
        }
    }

感谢您的帮助! :)

【问题讨论】:

  • 只需创建一个 UserPolicy 并创建一个方法来检查他是否已经发布了文章。第二种解决方案是您可以使用唯一的验证规则。有关用户策略的更多信息,请检查 laravel 5.3 @AriandoMiller 的授权
  • 我知道我可以使用策略和门来做到这一点,但我的问题是逻辑看起来像@PassionInfinite
  • 嘿@PassionInfinite 你还在吗?我今天才意识到这不起作用,即使用户尚未在给定版本中发布任何文章,它也会不断返回错误消息
  • @PassionInfinite 我已经用控制器更新了我的问题。抱歉,我无法加载讨论,我的连接现在超级慢
  • 对不起,你是什么意思?@PassionInfinite

标签: laravel laravel-5


【解决方案1】:

可行的解决方案是你只需要在其中创建 UserPolicy 和一个方法来检查用户是否已经创建了文章。像这样

UserPolicy 将有这样的方法:

    public function userHasArticle(User $user, $edition_id){
        //Made Article Model
        $article = Article::query()->where('user_id', $user->id)->where('id_edition', $edition_id)->get();
        if(is_null($article)){
            return true;
        }else{
            return false;
        }
    }

而在控制器中逻辑应该是这样的:

protected $usersPolicy;

public function __construct(UsersPolicy $usersPolicy)
{
    $this->usersPolicy = $usersPolicy;
}


public function post(Request $request){
    //First check like this
    //Get the id_edition and before processing anything first check this condition

    if($this->usersPolicy->userHasArticle(auth()->user(), $id_edition)){

    }else{
        //Return Error!
    }

}

确保 UserPolicy 具有 use HandlesAuthorization 特征 希望!你明白我的观点。有任何疑问评论下方! :)

【讨论】:

  • 控制器中的这一行 ($this->userPolicy->userHasJournal(auth()->user(), $id_edition)) 给我错误“未定义的变量 id_edition”。我是否必须在我的控制器中定义它,例如 "$id_edition = Edition::findOrFail($id)" 这个? @PassionInfinite
  • 您必须找到哪个 edition_id 是用户试图发布文章并将其存储在 $edition_id 变量中。 @AriandoMiller
  • 好的,知道了!立即尝试
  • 成功了!但是你在这里有点错过了“$article = User::query()....”,它应该是这样的,而不是“$article = Article::query()....”。但无论如何,非常感谢您的帮助! :)
  • 其实我是在我的编辑器里给你写demo代码,所以我在那边搞错了!对不起!。 @AriandoMiller
【解决方案2】:

它现在确实有效,所以我在我的控制器中做了这样的事情而没有使用策略(将在此处写下来以防有人需要它)

public function storearticle(ArticleRequest $request) {
        $input = $request->all();
        $input['user_id'] = Auth::id();
        $idi = $request->id;
        $articlerules = Article::where('id_edition', $idi)
                ->where('user_id', $request->user()->id)
                ->exists();
        if ($articlerules == true) {
            return 'You already have an article in this edition, please pick another edition instead.';
        } else {
            if ($request->hasFile('file')) {
                $input['file'] = $this->uploadPDF($request);
            }

            //Insert article datas
            $article = Edition::findOrFail($idi)->article()->create($input);
            $article->user()->attach($request->input('authors'));

            return redirect()->route('edition', ['id' => $idi]);
        }
    }

【讨论】:

  • @PassionInfinite 我现在终于做到了,但我仍然感谢您为帮助我付出的巨大努力:)
猜你喜欢
  • 2015-08-14
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多