Rails 4 - Pundit - 制定政策

时间:2016-07-25 00:32:57

标签: ruby-on-rails ruby pundit

我试图弄清楚如何在我的Rails 4应用中使用pundit。

我有一个个人资料视图,其中我想显示一个链接来创建一个新项目,但需要获得权威授权。

我尝试了以下每种配方:

 <%# if policy(Project.new).create? %>
                            <%# if policy(Project).create? %>
                            <%# if policy(@project).create? %>
                            <%# if policy(Projects).create? %>
                            <% if policy(project).create? %>


                             <%= link_to 'CREATE A PROJECT', new_project_path, :class=>"btn btn-info"  %>
                            <% end %> 

项目和个人资料之间的关联是:

项目

belongs_to :profile

资料

has_many :projects, dependent: :destroy

我的项目政策有:

def new?
        true
        # create?
    end

    def create?
        true

    end

当我在个人资料视图中尝试使用此行时:<% if policy(Project).create? %>

我收到错误消息:

  

错误的参数数量(给定2,预期为0)

当我在个人资料视图中尝试使用此行时:<% if policy(@project).create? %>

我收到错误消息:

  

错误的参数数量(给定2,预期为0)

当我在个人资料视图中尝试使用此行时:<% if policy(Projects).create? %>

我收到错误消息:

  

无法找到nil的政策

当我在个人资料视图中尝试使用此行时:<% if policy(project).create? %>

我收到错误消息:

  

未定义的局部变量或方法`project&#39;对于   &LT;#:0x007faf5255d468&GT;你的意思是? project_url

如果视图页面位于不同的模型中(例如,配置文件,测试该配置文件的授权是否可以创建项目),我是否需要做一些特殊的测试项目授权?我已经陷入困境并猜测如何解决这个问题。

在我的项目控制器中,我有一个创建方法:

def create
    @project = Project.new(project_params)
    @project.profile = current_user.profile

    respond_to do |format|
      if @project.save
        format.html { redirect_to @project }
        format.json { render :show, status: :created, location: @project }
      else
        format.html { render :new }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

政策的初始化:

class ProjectPolicy < ApplicationPolicy

    attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

2 个答案:

答案 0 :(得分:0)

看起来您的代码可能没有必要的实例变量。在show方法中你应该有一个@project - 你可以使用Pundit来检查用户是否可以创建它。

由于您似乎没有@project,您可以尝试这样做:

<% if policy(Project.new).create? %>

您也可以尝试使用符号:

policy(:project)

<% if policy(:dashboard).show? %>
  <%= link_to 'Dashboard', dashboard_path %>
<% end %>

您是否有这样定义的政策?

# app/policies/project_policy.rb
class ProjectPolicy < Struct.new(:user, :project)
  # ...
end

答案 1 :(得分:0)

通常我会在视图中使用另一个类,例如ViewPolicy:

class ViewPolicy < Struct.new(:user, :views)

    def items_index?
        user.has_role?(:sales)
    end

end

所以我可以这样做:

<% if policy(:views).items_index? %>
  <%= link_to("Items", items_path) %>
<% end %>

与@Kieran Andrews非常相似