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!
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With