如何让用户只看到编辑和删除链接,如果文章是他们自己的?

问题描述:

我的用户是通过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 

当你有机会获得由设计所提供的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。 –