问题
I'm pretty new with Rails and I have a problem with the following policies (using Pundit): I'd like to compare two objects: @record
and @foo
, as you can see here:
class BarPolicy < ApplicationPolicy
def show?
@record.foo_id == @foo
end
end
I don't reach to find a good way to pass a second parameter to pundit methods (@foo).
I'd like to do something like:
class BarsController < ApplicationController
def test
authorize bar, @foo, :show? # Throws ArgumentError
...
end
end
But the Pundit authorize method allows only two parameters. Is there a way to solve this issue?
Thanks!
回答1:
I found the answer at here.
Here is my way:
Add a pundit_user
function in ApplicationController
:
class ApplicationController < ActionController::Base
include Pundit
def pundit_user
CurrentContext.new(current_user, foo)
end
Create the CurrentContext
class:
/lib/pundit/current_context.rb
class CurrentContext
attr_reader :user, :foo
def initialize(user, foo)
@user = user
@foo = foo
end
end
Update the initialize Pundit method.
class ApplicationPolicy
attr_reader :user, :record, :foo
def initialize(context, record)
@user = context.user
@foo = context.foo
@record = record
end
end
回答2:
Relying on more than the current user and a domain model is a code smell, but in case it really is required, then you can use a custom query method with any number of parameters and raise an exception if the requirements don't met:
class BarPolicy < ApplicationPolicy
def authorize_test?(foo)
raise Pundit::NotAuthorizedError, "not authorized to test" unless record.foo_id == foo
end
end
class BarsController < ApplicationController
def test
skip_authorization && BarPolicy.new(current_user, @record).authorize_test?(@foo)
...
end
end
The skip_authorization &&
part is not required if after_action :verify_authorized
is not used, I just wanted to show a one-liner that can be used in this case to get rid of the not-authorized exception while still having the requirement to authorize the action.
来源:https://stackoverflow.com/questions/28216678/pundit-policies-with-two-input-parameters