我的应用中有一个权限模型,它将(用户,角色,项目)绑定在一起。
我想要学习的是阻止用户为自己的项目移除自己......
您能否就以下内容向我提供反馈?
class Permission < ActiveRecord::Base
.
.
.
#admin_lock makes sure the user who created the project, is always the admin
before_save :admin_lock
def before_save
#Get the Project Object
project = Find(self.project_id)
if project.creator_id == current_user.id
# SOME HOW ABORT OR SEND BACK Not Allowed?
else
#continue, do nothing
end
end
end
这看起来是正确的做法吗?
另外,我不确定如何做以下两件事:
感谢您阅读
答案 0 :(得分:2)
如何中止阻止保存,并发回错误消息?
在回调链中返回false告诉activemodel停止(类似于在验证期间向模型添加错误告诉它在该点停止的方式)
self.errors.add_to_base“msg”会向模型添加一个错误,然后可以在视图上呈现。
获取模型中的devise,current_user.id,这似乎不太可能,那么Rails大师们如何做上面的事情呢?
模型不应该真正了解当前请求之类的内容,如果可能的话,你应该在控制器/操作级别锁定内容。
编辑:
因此,控制器的作用是处理根据请求获取正确信息所涉及的所有内容,并将其传递给视图(后者成为响应)。人们经常说“让你的模型变胖,你的控制器变瘦”,但可以说任何采用面向对象设计的系统 - 你的逻辑应尽可能在对象中。
话虽这么说,控制器的重点是处理将正确的东西路由到正确的位置,并且身份验证绝对是路由的关注点。
您可以轻松地将行中的creator_id与用户ID进行比较,并根据该行做出反应。
现在,有时你真的需要模型中的那些东西而且没有办法绕过它。这成为一个问题,因为你需要与铁路对抗以实现它。一种方法是attr_accessor模型上的current_user字段,并在初始化时传入。另一种方法是从params散列中删除不允许用户在操作中更改的字段。虽然不是那么好。
答案 1 :(得分:1)
同意Matt你应该尝试使用控制器进行重定向。该模型应具有确定重定向是否合适的逻辑。也许像是
class ProjectsController < ApplicationController
def update
redirect_to(projects_url, :alert => "You can't remove yourself from this project.") and return if Role.unauthorized_action?(:update, params[:project])
@project = Project.find(params[:id])
if @project.update_attributes(params[:project])
...
end
class Role
def self.unauthorized_action?(action, params)
# your logic here
end
您应该查看CanCan以获取一些想法。
答案 2 :(得分:0)
before_create :set_project_ownership def set_project_ownership self.permissions.build(user_id: User.current.id, project_creater: true) end
before_filter :set_current_user
def set_current_user User.current = current_user end