0

用户 has_many 构造用户,后者是 has_many 的连接表:通过与 Construct 的关系。出于应用目的,布尔角色定义在连接表中(constructusers.manager、constructusers.operator 等),而 admin 是用户属性。

因此,当需要定义有关操作的策略时,以下会为“经理”引发无方法错误,而识别出关系 ActiveRecord::Relation:0x000001035c4370

  def show?
    user.admin? or user.constructusers.manager?
  end

如果关系(我假设是正确的)是正确的,为什么没有识别布尔属性?

根据下面的评论,原因很简单,就是复数。因此过滤需要:

Constructuser.where(['construct_id = ? and user_id = ?', params[:id], current_user]).first

...它在控制器中运行并影响视图。尽管如此,对于正确的 Pundit 处理,这需要被排除在外......仍然在前过滤器中 de application_controller 以设置该属性。但是,具有该查找条件的 before_filter :set_constructuser_manager 以及 nil 案例处理在说明策略时仍然没有影响

  def show?
    set_constructuser_manager?
  end

更新:根据下面的评论。Pundit 类私有方法

def contractorconstruct 
  @contructs = Construct.where(['constructusers.user_id = ?', user]).joins(:users).all
  @contractorconstruct ||= Contractor.where(['construct_id IN (?)', @contructs]).first
end

和动作规则

|| contractorconstruct?

不返回任何方法错误。

4

1 回答 1

1

manager?将是 Constructuser 实例上的方法,而不是关系上的方法。想想你在问什么,“这个constructusers是一个经理吗?” - 这没有道理。计算机如何知道您在说什么constructuser?

如果一个用户有_many 构造用户,为了使用manager?你需要找到你关心的实例。如果这是在 ConstructPolicy 中,那么您需要找到链接user到您正在授权的构造的特定构造用户,然后检查该单个构造用户是否为manager?.

如果你在 Construct 控制器中,你会有类似的东西

class ConstructsController

  before_action :set_construct

  def show
    authorize @construct
    # ...
  end

  # ...

end

那么,在您的策略中,user将是当前用户,并且record将是@construct.

class ConstructPolicy

  def show?
    user.admin? || constructuser.manage?
  end

  private

    def constructuser 
      @constructuser ||= Constructuser.find_by(user_id: user, construct_id: record)
    end

end
于 2013-11-28T16:09:53.180 回答