2016-11-21 295 views
0

我在我的應用程序中有這種情況,我必須限制可以由用戶編寫的帖子。例如,我有一個名爲Edition的表來存儲版本數據和Article表來存儲文章數據。版表和文章表有一對多的關係(一版有很多文章)。現在,我有一個Users表來存儲用戶數據,並且這個表與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'; 
     } 
    } 

謝謝你的幫助! :)

+0

只是做一個UserPolicy並創建一個方法檢查他是否已經發布文章。第二個解決方案是你可以使用獨特的驗證規則。有關用戶策略的更多信息,請查看laravel的授權5.3 @AriandoMiller – PassionInfinite

+0

我知道我可以使用policy和gate來做到這一點,但是我的問題是邏輯看起來像@PassionInfinite –

+0

hey @PassionInfinite你還在嗎?我今天才意識到這不起作用,即使用戶還沒有發佈任何文章,但它仍然返回錯誤消息 –

回答

2

可行的解決方案是,你只需要使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特質 希望!你明白了我的觀點。任何查詢下面評論! :)

+0

這行在控制器($ this-> userPolicy-> userHasJournal(auth() - > user(),$ id_edition))給我錯誤「未定義的變量id_edition」。我是否必須在我的控制器中定義它,如「$ id_edition = Edition :: findOrFail($ id)」這個?@PassionInfinite –

+0

你必須找到哪個edition_id是試圖發佈文章並將其存儲在$ edition_id變量中的用戶。 @AriandoMiller – PassionInfinite

+0

好的,明白了!現在嘗試它 –

0

它的確現在的工作,所以我做了這樣的事情在我的控制器不使用政策(會寫下來,在這裏萬一有人需要它)

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]); 
     } 
    } 
+0

@PassionInfinite我終於做到了,但是我仍然感謝你爲幫助我而付出的巨大努力:) –