简体   繁体   English

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

[英]How to allow users to only see edit and delete link if the article is their own?

My users are set up through Devise.我的用户是通过 Devise 设置的。 I also can use CanCanCan.我也可以使用 CanCanCan。

I set up an articles model and any user can create articles.我建立了一个文章模型,任何用户都可以创建文章。 They can only delete and edit their own article creations.他们只能删除和编辑自己的文章创作。 On the index, they can view all articles that have been created by all users.在索引上,他们可以查看所有用户创建的所有文章。 There is currently an option to View, Edit, and Delete.目前有查看、编辑和删除选项。 I only want that option visible on the articles that are owned by the user.我只希望该选项在用户拥有的文章上可见。 I want all other article lines to be blank.我希望所有其他文章行都是空白的。 (Except for admin of course.) Users can view posts on views/articles/index.html.erb (当然管理员除外。)用户可以在 views/articles/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>

How can I allow users to only see the Edit and Delete button on the post that they own?如何让用户只能看到他们拥有的帖子上的“编辑”和“删除”按钮?

I tried this but it does not work:我试过这个,但它不起作用:

<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>

I've also tried:我也试过:

      <% if current_user && current_user.articles.exists?(@article.id) %>

Here is what my articles controller looks like: (I know I need to make it look better.)这是我的文章控制器的样子:(我知道我需要让它看起来更好。)

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

As you have access to the current_user helper provided by Devise, then you can compare it with the article's owner.由于您可以访问 Devise 提供的current_user帮助程序,因此您可以将其与文章的所有者进行比较。 This can be in the view, to render the proper links to perform the actions:这可以在视图中呈现正确的链接以执行操作:

<% @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 %>

You can move this verification to a helper, in the ApplicationHelper to be available in most of your views, like:您可以将此验证移动到一个助手,在 ApplicationHelper 中可以在您的大多数视图中使用,例如:

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

You pass the object, and this returns true or false depending if the current user is equal to the object user.您传递对象,这将根据当前用户是否等于object用户返回 true 或 false。 The view only changes to:视图仅更改为:

<% if owner?(article) %>

If you want to move this verification to the controller, or also if you want to use it in both cases, then you can do the same verification in the controller.如果您想将此验证移动到控制器,或者如果您想在两种情况下都使用它,那么您可以在控制器中进行相同的验证。 As the owner?作为owner? helper method isn't available in the controller, you can just redirect back in case the current_user isn't the article's owner, like: helper 方法在控制器中不可用,如果 current_user 不是文章的所有者,您可以重定向回来,例如:

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

If you want to move this part to a before callback, to be able to use it in the edit and destroy method, then you can add it as a private method, and having access to the @article you can do such comparison, it'd be:如果你想把这部分移动到一个before回调中,以便能够在editdestroy方法中使用它,那么你可以将它添加为私有方法,并且可以访问@article你可以进行这样的比较,它d 是:

private

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

This way you just need to add it as a before_action callback:这样你只需要将它添加为before_action回调:

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

Most probably before the one that defines the @article variable.很可能在定义 @article 变量之前。

Note the use of redirect_back in Rails 5, previous versions might use redirect_to :back .注意使用的redirect_back Rails中5,以前的版本可能会使用redirect_to :back

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM