I’m having a problem while using ViewComponent with Dry Monads. Here my code:
require "dry/monads"
class Dashboard::Course::Marketing::StatsComponent < ViewComponent::Base
include Dry::Monads[:result, :do]
def initialize(course:)
@course = course
end
end
But this give me the error:
NoMethodError in Dashboard::Course::Marketing::Marketing#index
super: no superclass method `call' for
#<Dashboard::Course::Marketing::StatsComponent:0x00007fa01f1c5d38
If I remove the require "dry/monads", the code starts working again. What could be causing this issue?
I found a way to work around the issue as follows:
require "dry/monads/do"
include Dry::Monads::Do.for(:fetch_video_and_signature) # a specif method where I'm using the gem
I tried to be as specific as possible and included it within a method where the Dry Monads gem was being used. However, I’m still uncertain about the root cause of the problem.
Taking a look at the ViewComponent docs, call is not part of the public interface. So that’s what’s happening: Dry::Monads::Do::All is expected a call method and you don’t have one.
Furthermore, I don’t think mixing in do-notation into a ViewComponent is a good idea. It’s meant for Operation objects that behave like functions, and isn’t really used in view logic that I’ve seen. The do-notation wraps every method defined with code that intercepts yield, which is a bad idea in views, yield is usually used for something.
The workaround you’ve already found, using include Dry::Monads::Do.for for specific methods should be safe to do. But if wrapping a helper method in do-notation is necessary here, then perhaps that would be better off extracted into a separate Operation.