我正在创建类似于Reddit的网站。我想允许主持人能够更新主题,但无法创建或删除主题。我知道我需要更新TopicsController,但我不确定如何。我的主要问题是,我不确定如何使代码具体到足以确保主持人只能更新;不要像管理员那样删除或创建主题。
我目前的代码如下:
class PostsController < ApplicationController
before_action :require_sign_in, except: :show
before_action :authorize_user, except: [:show, :new, :create]
def show
@post = Post.find(params[:id])
end
def new
@topic = Topic.find(params[:topic_id])
@post = Post.new
end
def create
@post.body = params[:post][:body]
@topic = Topic.find(params[:topic_id])
@post = @topic.posts.build(post_params)
@post.user= current_user
if @post.save
flash[:notice] = "Post was saved"
redirect_to [@topic, @post]
else
flash[:error] = "There was an error saving the post. Please try again."
render :new
end
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
@post.assign_attributes(post_params)
if @post.save
flash[:notice] = "Post was updated."
redirect_to [@post.topic, @post]
else
flash[:error] = "There was an error saving the post. Please try again."
render :edit
end
end
def destroy
@post = Post.find(params[:id])
if @post.destroy
flash[:notice] = "\"#{@post.title}\" was deleted successfully."
redirect_to @post.topic
else
flash[:error] = "There was an error deleting the post."
render :show
end
end
private
def post_params
params.require(:post).permit(:title, :body)
end
def authorize_user
post = Post.find(params[:id])
unless current_user == post.user || current_user.admin?
flash[:error] = "You must be an admin to do that."
redirect_to [post.topic, post]
end
end
end
我已经为枚举角色添加了一个主持人角色。
如果这看起来非常基本,我道歉......但它让我感到难过!
提前致谢!
答案 0 :(得分:0)
我可以使用一些自定义解决方案来回答,但最好使用更加结构化和社区审核的方法:使用cancan进行授权。
答案 1 :(得分:0)
作为tompave noticed,你可以使用cancan gem。 我个人更喜欢pundit。
在过去,我曾经在代码中直接定义权限:在控制器,视图甚至模型中。但这是非常糟糕的做法。当你的应用程序增长时,你会迷失:你更新了一个视图,但你应该在控制器中进行相同的更改,有时也在模型中进行更改。它很快变得绝对无法管理,你不知道你的用户能做什么,不能做什么。
另一方面,Pundit提供了中心位置 - 政策 - 用于定义用户可以执行的操作。然后,视图和控制器可以使用这些策略。
例如,如果您需要定义Post
的政策,则只需创建app/policies/post_policy.rb
文件:
class PostPolicy
attr_reader :user
attr_reader :post
def initialize(user, post)
@user = user
@post = post
end
def author?
post.user == user
end
def update?
author? || user.admin? || user.moderator?
end
def create?
author? || user.admin?
end
def destroy?
author? || user.admin?
end
# etc.
end
现在,只要您需要检查用户执行操作的能力,您只需调用:
# in controller
def update
@post = Post.find(params[:id])
authorize @post
# do whatever required
end
# in view
<% if policy(post).update? %>
<%= link_to 'Edit Post', post_edit_path(post) %>
<% end %>
正如您所看到的,Pundit非常容易理解,它使用与配置相同的约定&#34;作为Rails的方法。同时它非常灵活,允许您测试几乎任何东西。
您肯定需要Pundit或任何类似的宝石来管理您雄心勃勃的应用中的权限。