2017-10-08 60 views
2

我的用戶是通過Devise設置的。我也可以使用CanCanCan。如何讓用戶只看到編輯和刪除鏈接,如果文章是他們自己的?

我設置了文章模型,任何用戶都可以創建文章。他們只能刪除和編輯自己的文章作品。在索引上,他們可以查看所有用戶創建的所有文章。目前有一個選項可用於查看,編輯和刪除。我只希望該選項在用戶擁有的文章中可見。我希望所有其他文章行都是空白的。 (除了當然的管理員。) 用戶可以查看視圖/篇帖子/ index.html.erb

<table> 
    <tr> 
    <th>Title</th> 
    <th>Description</th> 
    </tr> 

    <% @articles.each do |article| %> 
    <tr> 
     <td><%= article.title %></td> 
     <td><%= article.description %></td> 
     <td><%= link_to 'View', article_path(article) %></td> 
     <td><%= link_to 'Edit', edit_article_path(article) %></td> 
     <td><%= link_to 'Delete', article_path(article), 
       method: :delete, 
       data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
    <% end %> 
</table> 

我怎樣才能讓用戶看到的只是編輯和刪除他們擁有的帖子按鈕?

我試過,但它不工作:

<table> 
    <tr> 
    <th>Title</th> 
    <th>Description</th> 
    </tr> 

    <% @articles.each do |article| %> 
    <tr> 
     <td><%= article.title %></td> 
     <td><%= article.description %></td> 
     <td><%= link_to 'View', article_path(article) %></td> 
     <% if user_signed_in? && current_user.articles.exists?(@article.id) %> 
     <td><%= link_to 'Edit', edit_article_path(article) %></td> 
     <td><%= link_to 'Delete', article_path(article), 
       method: :delete, 
       data: { confirm: 'Are you sure?' } %></td> 
     <% end %> 
    </tr> 
    <% end %> 
</table> 

我也試過:

​​

這裏是我的文章控制器看起來像:(我知道我需要使它更好看。)

def create 
    @article = current_user.articles.build(article_params) 

    if @article.save 
    redirect_to @article 
    else 
    render 'new' 
    end 
end 


def update 
    @article = Article.find(params[:id]) 
    if user_signed_in? && current_user.articles.exists?(@article.id) 
    if @article.update(article_params) 
     redirect_to @article 
    else 
    render 'edit' 
    end 
    elsif current_user && current_user.admin_role? 
    if @article.update(article_params) 
     redirect_to @article 
    else 
    render 'edit' 
    end 
    else 
    redirect_to @article 
    end 
end 

def destroy 
    @article = Article.find(params[:id]) 
    if user_signed_in? && current_user.articles.exists?(@article.id) 
    @article.destroy 
    redirect_to articles_path 
    elsif current_user && current_user.admin_role? 
    @article.destroy 
    redirect_to articles_path 
    else 
    redirect_to articles_path 
    end 
end 

回答

1

當你有機會獲得由設計所提供的current_user幫手,那麼你就可以COM把它與文章的所有者相提並論。這可以在視圖,以呈現正確的鏈接進行操作:

<% @articles.each do |article| %> 
    <tr> 
    <td><%= article.title %></td> 
    <td><%= article.description %></td> 
    <td><%= link_to 'View', article_path(article) %></td> 
    <% if current_user == article.user %> 
     <td><%= link_to 'Edit', edit_article_path(article) %></td> 
     <td><%= link_to 'Delete', article_path(article), 
       method: :delete, 
       data: { confirm: 'Are you sure?' } %></td> 
    <% end %> 
    </tr> 
<% end %> 

您可以在此驗證移動到一個幫手,在ApplicationHelper在大多數的意見是可用的,如:

module ApplicationHelper 
    def owner?(object) 
    current_user == object.user 
    end 
end 

您傳遞該對象,並根據當前用戶是否等於object用戶返回true或false。僅查看更改爲:

<% if owner?(article) %> 

如果你想這個驗證移動控制器,或者也可以,如果你想在這兩種情況下使用它,那麼你可以做同樣的驗證控制器。作爲owner?輔助方法,在控制器不可用,你可以重定向回萬一CURRENT_USER不是文章的所有者,如:

def edit 
    unless current_user == @article.user 
    redirect_back fallback_location: root_path, notice: 'User is not owner' 
    end 
end 

如果你想這部分移動到before回調,要能夠使用它在editdestroy方法,那麼你可以將其添加爲一個私有方法,以及具有訪問@article你可以做這樣的比較,這將會是:

private 

def owner? 
    unless current_user == @article.user 
    redirect_back fallback_location: root_path, notice: 'User is not owner' 
    end 
end 

這樣你只需要將其添加爲before_action回調:

before_action :owner?, only: %i[edit destroy] 

最可能在定義@article變量之前。

請注意在Rails 5中使用redirect_back,以前的版本可能使用redirect_to :back

+0

謝謝你的幫助。我目前遠離電腦,但稍後會嘗試一下。 –

+0

你給了我一些不錯的選擇。 –

+0

很高興幫助你@KadeWilliams。 –

相關問題