【问题标题】:Rails3 - Permission Model Before_Save Check?Rails3 - 权限模型 Before_Save 检查?
【发布时间】:2010-11-03 00:08:01
【问题描述】:

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

我希望学习如何做的是防止用户为他们的项目删除自己...

您能就以下问题给我反馈吗?

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 大师如何做上述事情?

感谢阅读

【问题讨论】:

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


    【解决方案1】:

    如何中止阻止保存,并返回错误消息?

    在回调链期间返回 false 告诉 activemodel 停止(类似于在验证期间向模型添加错误告诉它在该点停止)

    self.errors.add_to_base "msg" 会给模型添加一个错误,然后可以在视图上渲染。

    在模型中获取设计,current_user.id,这似乎是不可能的,那么 Rails 大师如何做类似上述的事情?

    模型不应该真正了解当前请求之类的事情,如果可能的话,您应该将事情锁定在控制器/操作级别。

    编辑:

    因此,控制器的作用是处理所有相关的事情,根据请求将正确的信息集中在一起,并将其传递给视图(即成为响应)。人们常说“让你的模型变胖,让你的控制器变瘦”,但任何包含面向对象设计的系统都可以这么说——你的逻辑应该尽可能在对象中。

    话虽如此,控制器的全部意义在于处理将正确的事情路由到正确的位置,而身份验证绝对是路由的一个关注点。

    您可以在操作中轻松移动将 creator_id 与用户 ID 进行比较的行,并据此做出反应。

    现在,有时您确实需要模型中的这些东西,但没有办法绕过它。这成为一个问题,因为您需要与铁轨作斗争才能到达那里。一种方法是 attr_accessor 模型上的 current_user 字段,并在初始化时将其传递。另一种方法是从参数哈希中删除不允许用户在操作中更改的字段。不过两者都不是很好。

    【讨论】:

    • 马特 - 谢谢。因此,如果模型不应该知道 current_user。我如何在控制器级别执行此操作。在控制器的某个地方我做了类似admin_lock(current_user)的事情? admin_lock 住在哪里,是在控制器还是模型中?我有点困惑,因为我认为模型应该做所有这些类型或权限/验证的东西,而控制器是真正的轻量级?帮忙?
    • 编辑了我的答案,抱歉我没有更好的东西给你:)
    【解决方案2】:

    同意 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 以获得一些想法。

    【讨论】:

      【解决方案3】:
      1. 在权限模型中,将一个字段 project_creater 作为布尔值
      2. 在项目模型中
        before_create :set_project_ownership
          def set_project_ownership
             self.permissions.build(user_id: User.current.id, project_creater: true)
          结束
      3. 在项目控制器中
        before_filter :set_current_user
      4. 在应用程序控制器中
        def set_current_user
          User.current = current_user
        结束

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 2016-07-22
        • 2012-06-04
        相关资源
        最近更新 更多