Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by AstralScholar559

How can I fix a Sorbet type error for a helper module missing base_method in controllers?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I have two controller classes (FooController and BarController) that inherit from ApplicationController. Both include a Helper module that defines a helper_method which calls base_method. However, after removing the method from the base class, Sorbet complains that base_method does not exist on Helper.

Here is the setup:

RUBY
# typed: true extend T::Sig class ApplicationController def base_method end end module Helper def helper_method base_method # -> Method base_method does not exist on Helper end end class FooController < ApplicationController include Helper end class BarController < ApplicationController include Helper end FooController.new.helper_method BarController.new.helper_method

I’ve read some suggestions (like using requires_ancestor or converting Helper into an interface) and wanted to see if there’s a simpler solution or a best practice in this scenario.

Any suggestions?

0

Comments 0

Answers 2

Views 66

2 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

You need to tell Sorbet that any class including Helper will have a base_method. One common approach is to declare Helper as an interface (or abstract mixin) that requires base_method. For example:

RUBY
# typed: true extend T::Sig require 'sorbet-runtime' module Helper extend T::Helpers interface! # Marks this module as an interface for type-checking # Declare that including classes must implement base_method sig { abstract.returns(T.untyped) } def base_method; end sig { returns(T.untyped) } def helper_method base_method end end class ApplicationController # Implements the required method def base_method "base implementation" end end class FooController < ApplicationController include Helper end class BarController < ApplicationController include Helper end puts FooController.new.helper_method puts BarController.new.helper_method

In this example, we use T::Helpers to mark Helper as an interface and declare base_method as abstract. This lets Sorbet know that any class mixing in Helper must implement base_method (which ApplicationController does), clearing the error.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by EtherealPathfinder050 1 month ago

0

This is why the requires_ancestor feature was added. Normally, you have no guarantees that your module will be included into a class with the methods that you expect, so Sorbet also can't find what base_method refers to.

However, with requires_ancestor you can say that your module requires that it be included into a class that has ApplicationController as an ancestor, and that allows Sorbet to both guarantee that base_method will always exist, and guarantee that you can't include Helper into any class that doesn't inherit from ApplicationController.

See this Sorbet Playground example for how it works and here is what the resulting code looks like:

RUBY
# typed: true extend T::Sig class ApplicationController def base_method end end module Helper extend T::Helpers requires_ancestor { ApplicationController } def helper_method base_method # this should not error. ignore the red squiggly! end end class FooController < ApplicationController include Helper end class BarController < ApplicationController include Helper end class NotAController include Helper # this should error end FooController.new.helper_method BarController.new.helper_method

One note is that this feature is still experimental, so needs to be turned on in sorbet/config explicitly using the --enable-experimental-requires-ancestor flag.

No comments yet.

Discussion

No comments yet.