{"record":{"id":"7a39f9c3ac575a0b","repo":"varvet/pundit","slug":"you-must-define-resolve-in-self-class","errorCode":null,"errorMessage":"You must define #resolve in #{self.class}","messagePattern":"You must define #resolve in #(.+?)","errorType":"exception","errorClass":"NoMethodError","httpStatus":null,"severity":"error","filePath":"lib/generators/pundit/install/templates/application_policy.rb.tt","lineNumber":46,"sourceCode":"    false\n  end\n\n  def edit?\n    update?\n  end\n\n  def destroy?\n    false\n  end\n\n  class Scope\n    def initialize(user, scope)\n      @user = user\n      @scope = scope\n    end\n\n    def resolve\n      raise NoMethodError, \"You must define #resolve in #{self.class}\"\n    end\n\n    private\n\n    attr_reader :user, :scope\n  end\nend\n","sourceCodeStart":28,"sourceCodeEnd":54,"githubUrl":"https://github.com/varvet/pundit/blob/06318683c960066a2e499341cb372e0ff4540334/lib/generators/pundit/install/templates/application_policy.rb.tt#L28-L54","documentation":"Pundit's generated ApplicationPolicy ships Scope#resolve as an abstract placeholder that raises NoMethodError. Every policy's nested Scope class must override #resolve to return the records the current user may see (typically an ActiveRecord::Relation or array). Pundit calls resolve after instantiating the scope class with (user, model), so inheriting the placeholder unimplemented makes the raise fire.","triggerScenarios":"Calling any scope-resolution API on a record whose policy Scope does not define #resolve: `pundit.policy_scope(Post)` / `Pundit.policy_scope(user, Post)` in a controller, `pundit.policy_scope!(Post)`, or `Pundit::PolicyFinder.new(Post).scope.resolve` — when `PostPolicy::Scope < ApplicationPolicy::Scope` and no `def resolve ... end` exists in it.","commonSituations":"Running the pundit:install generator, then hand-writing a policy with only query predicates (show?, edit?) and forgetting the nested Scope; copying a policy file that omits Scope; adding pundit to an existing app and only covering authorize-style checks before the first index action calls policy_scope; inheriting from ApplicationPolicy::Scope assuming the base provides a default resolve.","solutions":["Open the policy class named in the error message and add a nested `class Scope` with a `def resolve` that returns the permitted collection, e.g. `scope.where(user: user)`.","If everything should be visible to this policy's users, return `scope.all` (ActiveRecord) or just `scope` (PORO/array).","If several scopes share the same rule, implement resolve once in a shared base class and inherit from that instead of ApplicationPolicy::Scope.","Confirm the policy class in the message is the one being picked up (naming/namespace conventions) so you are editing the Scope Pundit actually instantiates."],"exampleFix":"# before\nclass PostPolicy < ApplicationPolicy\n  def show?\n    true\n  end\n  # no Scope — controller calls policy_scope(Post) and hits ApplicationPolicy::Scope#resolve\nend\n\n# after\nclass PostPolicy < ApplicationPolicy\n  def show?\n    true\n  end\n\n  class Scope < ApplicationPolicy::Scope\n    def resolve\n      scope.where(user: user)\n    end\n  end\nend","handlingStrategy":"validation","validationCode":"scope_class = Pundit::PolicyFinder.new(record).scope\n\nif scope_class.nil?\n  # no scope class at all — policy_scope returns nil; policy_scope! would raise NotDefinedError\nelsif scope_class.instance_method(:resolve).owner == ApplicationPolicy::Scope\n  # would hit the raising placeholder — do not call policy_scope on this record yet\nelse\n  pundit.policy_scope(record)\nend","typeGuard":"def implements_resolve?(scope_class)\n  return false if scope_class.nil?\n  scope_class.instance_method(:resolve).owner != ApplicationPolicy::Scope\nrescue NameError\n  false\nend","tryCatchPattern":"begin\n  pundit.policy_scope(record)\nrescue NoMethodError => e\n  raise unless e.message.include?(\"#resolve\") # only swallow the unimplemented-placeholder raise\n  # scope not implemented for this policy — fall back or re-raise a domain error\n  raise MissingPolicyScopeError, \"#{record.class}Policy::Scope must define #resolve\"\nend","preventionTips":["Generate every policy with `rails g pundit:policy Model` so the Scope skeleton (including resolve) is present from the start.","Write a shared policy spec example that calls `.resolve` on each policy's Scope, so an unimplemented resolve fails in tests before it reaches a controller.","If most scopes share one rule, implement #resolve in a common base class rather than relying on the ApplicationPolicy placeholder."],"tags":["ruby","pundit","authorization","abstract-method","policy-scope","no-method-error"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"06318683c960066a2e499341cb372e0ff4540334","analyzedAt":"2026-08-21T18:13:24.520Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}