Rails3 - 权限模型Before_Save检查?

时间:2010-11-03 00:08:01

标签: ruby-on-rails ruby-on-rails-3 devise

我的应用中有一个权限模型,它将(用户,角色,项目)绑定在一起。

我想要学习的是阻止用户为自己的项目移除自己......

您能否就以下内容向我提供反馈?

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

这看起来是正确的做法吗?

另外,我不确定如何做以下两件事:

  • 如何中止阻止保存,并发回错误消息?
  • 获取模型中的设计,current_user.id,这似乎是不可能的,那么Rails专家如何做上面的事情呢?

感谢您阅读

3 个答案:

答案 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)

  1. 在权限模型中,将一个字段project_creater作为boolean
  2. 在项目模型中
    before_create :set_project_ownership
      def set_project_ownership
         self.permissions.build(user_id: User.current.id, project_creater: true)
      end
  3. 在项目控制器
    before_filter :set_current_user
  4. 在应用程序控制器
    def set_current_user
      User.current = current_user
    end