我的用户是通过Devise设置的。我也可以使用CanCanCan。
我设置了一个文章模型,任何用户都可以创建文章。他们只能删除和编辑自己的文章创作。在索引上,他们可以查看所有用户创建的所有文章。目前有一个查看,编辑和删除选项。我只希望在用户拥有的文章上看到该选项。我希望所有其他文章行都是空白的。 (当然除了管理员。) 用户可以查看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>
如何让用户只能看到他们拥有的帖子上的“编辑”和“删除”按钮?
我尝试了这个,但它不起作用:
<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>
我也试过了:
<% if current_user && current_user.articles.exists?(@article.id) %>
这是我的文章控制器的样子:(我知道我需要让它看起来更好。)
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
答案 0 :(得分:1)
由于您可以访问Devise提供的current_user
帮助程序,因此您可以将其与文章所有者进行比较。这可以在视图中,以呈现正确的链接来执行操作:
<% @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
您传递了该对象,并返回true或false,具体取决于当前用户是否等于object
用户。视图仅更改为:
<% 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
回调,以便能够在edit
和destroy
方法中使用它,那么您可以将其添加为私有方法,并且可以访问@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
。