工具
**该项目**
项目回购在Github上; 这里正在审查的是pundit-1
分支机构.
我遵循了Pundit教程并使用"传统"胖乎乎的控制器获得了授权; 看到
PostsController#new
动作和它的规范 ;ApplicationPolicy
类 ; 和PostDataPolicy
邮件的Rails模型实例的管理授权.到目前为止一切顺利.然后我们来到SessionController
,其中#new
和#destroy
行动分别管理登录和退出..
在当前的代码和规范工作得很好用传统的上下的控制器逻辑(见如何#new
调用私有方法使用权威人士使用授权活动(当前)用户SessionDataPolicy
.
然后我试着来封装内的逻辑ActiveInteraction DSO(见注释掉的代码中SessionsController#new
),和所有的地狱破散.
更具体地说,此Gist中的SessionsController
规范版本在规范调用方法时引发了一个版本.Pundit::AuthorizationNotPerformedError
#new
威士忌酒.探戈.狐狸?!?!?
有没有人能够在没有 Pundit直接在控制器代码中生活的情况下使用类似的代码,理想情况下使用@ billychan的pull请求(更好的替代方案将非常感激)?
这让我完全 …
我想在Rails 4中创建一个应用程序.
我试图使用政治家宝石为州,然后专政政策.
我的gemfile有:
gem 'statesman', '~> 1.3', '>= 1.3.1'
gem 'pundit'
Run Code Online (Sandbox Code Playgroud)
我有一篇文章模型和一篇文章转换模型和一篇article_state_machine模型.
我的目标是在我的文章策略中定义发布策略(使用权威),允许拥有文章的用户在该文章处于"已批准"状态时发布该文章.
我在我的权威文章政策中尝试这个:
class ArticlePolicy < ApplicationPolicy
def publish?
user.present? && user == article.user
# if requires approval, then approved
# and article.in_state(:approve) - why doesnt this work - see statesman docs?
# user && user.article.exists?(article.id)
end
end
Run Code Online (Sandbox Code Playgroud)
当我尝试检查文章是否处于状态时:批准(如上所述),我收到一条错误消息,指出未定义的方法'in_state'.
如何在策略中使用状态机?或者是否该策略允许用户始终发布,但是当文章处于州批准状态时,您只在文章显示页面上显示按钮(尽管我认为这是专家的观点).
Article.rb
class Article < ActiveRecord::Base
include Statesman::Adapters::ActiveRecordQueries
has_many :transitions, class_name: "ArticleTransition", autosave: false
def state_machine
@state_machine ||= ArticleStateMachine.new(self, transition_class: ArticleTransition, association_name: :transitions)
end
# delegate :can_transition_to?. :trans
# …
Run Code Online (Sandbox Code Playgroud) 我对Rails很新,我对以下策略有问题(使用Pundit):我想比较两个对象:@record
并且@foo
,如您所见:
class BarPolicy < ApplicationPolicy
def show?
@record.foo_id == @foo
end
end
Run Code Online (Sandbox Code Playgroud)
我找不到将第二个参数传递给pundit方法(@foo)的好方法.
我想做点什么:
class BarsController < ApplicationController
def test
authorize bar, @foo, :show? # Throws ArgumentError
...
end
end
Run Code Online (Sandbox Code Playgroud)
但Pundit授权方法只允许两个参数.有没有办法解决这个问题?
谢谢!
的Gemfile
gem 'pundit', '~> 0.2.1'
Run Code Online (Sandbox Code Playgroud)
应用程序/控制器/ application_controller.rb
class ApplicationController < ActionController::Base
include Pundit
...
Run Code Online (Sandbox Code Playgroud)
应用程序/政策/ application_policy.rb
class ApplicationPolicy < Struct.new(:user, :record)
def index? ; false; end
def show? ; scope.where(id: record.id).exists?; end
def create? ; false; end
def new? ; create?; end
def update? ; false; end
def edit? ; update?; end
def destroy?; false; end
def scope
Pundit.policy_scope!(user, record.class)
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序/政策/ book_policy.rb
class BookPolicy < ApplicationPolicy
def create?
record.new_record?
end
def new?
create? end
def show?
record.published? || …
Run Code Online (Sandbox Code Playgroud) 在我的项目中,我有相当常见的命名空间"admin".
namespace :admin do
resources :users, except: :show
end
Run Code Online (Sandbox Code Playgroud)
我使用Pundit gem来设置适当的授权,但我发现在命名空间中使用控制器很困难.我的政策安排如下
-policies
-admin
user_policy.rb
application_policy.rb
admin_policy.rb
awesome_policy.rb
Run Code Online (Sandbox Code Playgroud)
与控制器非常相似.
但是,当在控制器内部使用"授权"方法时我只得到一个错误,通知该应用程序"无法找到UserPolicy".我的UserPolicy看起来像这样:
class Admin::UserPolicy < AdminPolicy
end
Run Code Online (Sandbox Code Playgroud)
那么问题是什么,我应该怎样做才能使Pundit在命名空间中看到这些策略?
我刚刚从CanCan切换到Pundit.我不确定有几件事,以及如何最好地使用Pundit.例如.
如果您有一个可以有多个父对象的资源,例如可以说一个目标属于一个学生和教师.因此,学生可以有很多目标,教师可以有很多目标.在控制器索引操作中,您可能会:
if params[:student_id].present?
@account = Student.find(params[:student_id])
@goals = @account.goals
elsif params[:instructor_id].present?
@account Instructor.find(params[:instructor_id])
@goals = @account.goals
end
Run Code Online (Sandbox Code Playgroud)
params在策略中不可用,因此逻辑需要在这里完成.我认为.据我所知,如果您跳过policy_scope,在查看目标索引页时会出现未经授权的错误.
你会:
@goals = policy_scope(@account.goals)
Run Code Online (Sandbox Code Playgroud)
要么
@goals = policy_scope(Goal.scoped).where( account_id: @account.id)
Run Code Online (Sandbox Code Playgroud)
当你在混合中抛出一堆包含时会发生什么?
@example = policy_scoped(@school.courses.includes(:account => :user, :teacher ))
Run Code Online (Sandbox Code Playgroud)
或者当需要订购时......这是正确的吗?policy_scope(Issue.scoped).order("created_at desc")
使用范围时:什么是:范围在这里?是:范围正在评估的模型的实例?我试过通过:scope访问它的属性,但是没有用.
policy_scope(Issue.scoped).order("created_at desc")
Run Code Online (Sandbox Code Playgroud) 我使用 pundit 进行授权,使用 RSpec 在我的 Rails 应用程序中进行测试。因此,我必须为策略创建规范。
但是,我遇到 rubocop 抛出错误的问题:RSpec/MultipleMemoizedHelpers。我明白这意味着我有太多的let
电话subject
。我的问题是我不太确定如何解决或重构我的代码,以便它符合我应该进行的正确调用次数。
另一件事,可以为规范文件禁用 RSpec/MultipleMemoizedHelpers 吗?
以下是三个存在问题的策略规范文件。
require "rails_helper"
describe AnswerPolicy do
subject { described_class }
let(:user_admin) { build(:user, :admin) }
let(:consultant) { build(:consultant) }
let(:user_consultant) { build(:user, :consultant, consultant: consultant) }
let(:client) { build(:client, consultant: consultant) }
let(:user_client) { build(:user, :client, client: client) }
let(:other_client) { build(:client, consultant: build(:consultant)) }
let(:answer) { build(:answer, client: client) }
let(:other_answer) { build(:answer, client: other_client) }
permissions :update? do
it "allows access …
Run Code Online (Sandbox Code Playgroud) 看来Pundit策略不访问会话参数.由于构造不会将会话重新组合为有效的变量或方法.有没有办法访问会话或其他参数?
class MyModelPolicy
def create?
@contructs = Construct.where(['id = ?', session[:construct_id]]).all
end
end
Run Code Online (Sandbox Code Playgroud) 我正在写关于https://github.com/elabs/pundit#scopes
我的印象是授权应该回答问题您是否允许访问此资源?,即true
/ false
答案.所有行动都属于这种情况,除了index
Pundit的文档,ActiveRecord::Relation
根据谁的要求,应该返回不同的行为.例如,管理员获取scope.all
,而普通用户获取scope.where(:published => true)
.
应用程序/政策/ post_policy.rb
class Scope < Struct.new(:user, :scope)
def resolve
if user.admin?
scope.all
else
scope.where(:published => true)
end
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序/控制器/ posts_controller.rb
def index
@posts = policy_scope(Post)
end
Run Code Online (Sandbox Code Playgroud)
我的保留意见是这是一个很滑的斜坡,很快我就会在范围内添加演示文稿(例如scope.all.order('created_at ASC')
) - 在授权政策中这样做很奇怪.
当然我可以把它移到控制器......
def index
@post = policy_scope(post)
if user.admin?
@post = @post.order( 'created_at ASC' )
end
end
Run Code Online (Sandbox Code Playgroud)
......但这是控制器的工作吗?而且我认为将这样的调用添加到视图中是不对的.那么也许它应该是一种模型方法?
你会说什么是做以下事情的利弊?
应用程序/控制器/ posts_controller.rb …
我正在使用Devise并且对使用Pundit感兴趣,但是如果它应该与Rolify集成或者它是独立的话,就无法找到.CanCanCan与Rolify很好地配合,我喜欢角色模型.我错过了Pundit和Rolify似乎没有一起使用的主要原因吗?