[英]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
回调中,以便能够在edit
和destroy
方法中使用它,那么你可以将它添加为私有方法,并且可以访问@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.