So I decided to give a try to pundit user authorization solution. I wonder how to use the policy
helper in view where an instance variable might be nil, as in the simple case below:
app/views/projects/index.html.slim
h1 Projects
(...)
- if policy(@project).create?
= link_to 'New Project', new_project_path
app/controllers/projects_controller.rb
(...)
def index
@projects = Project.all
end
(...)
app/policies/project_policy.rb
class ProjectPolicy < Struct.new(:user, :project)
def create?
user.has_role? :admin
end
I want to show a "New Project" link on Projects#index page, but I do not have a @project instance variable available in this view, getting an error:
Pundit::NotDefinedError in Projects#index
unable to find policy NilClassPolicy for
The error appears apparently because I do pass @project
instance variable that is nil, therefore has a NilClass which apparently I do not have a need to authorize.
I found 2 workarounds to this problem that make it run correctly, but none of them seems to be appropriate:
- Make use of existing @projects variable in the view, i.e.:
policy(@projects[0])
- add a line to projects#index controller action that defines this instance variable, ex.
@project = Project.new
(or directly in view similar to above:policy(Project.new)
)
First solution will cause same error in @projects array would be empty, while second one creates redundant instance variable. All policy helper needs to know is on which class I do want to enforce the authorisation logic.
Any suggestions on proper way to achieve it?