lost9123193
lost9123193

Reputation: 11040

Calling Methods from Inherited Class in Ruby

I have the following classes:

Module

module AlertService
    module MessageTemplate
      def generate_message
        "test"
      end
    end
  end

Parent class:

module Client
  def post uri, params={}
    Net::HTTP.post_form uri, params
  end
end

module AlertService
  class BaseAlert
    extend MessageTemplate
    include Singleton
    include Client
    def initialize; end
  end
end

Child Class:

module AlertService
class TestAlert < BaseAlert
  include Singleton
  def initialize
  options = {
    username: "Screen Alert Bot",
    http_client: Client
  }
  @notifier = Slack::Notifier.new(rails.config.url, options)
  end

  def self.create_message
    message = generate_message
  end

  def self.send_message
    create_message
    @notifier.post blocks: message
  end
end
end

I can create the test alert like this: s= AlertService::TestAlert

But I get the error when I do this:

s.send_message

NoMethodError: undefined method `generate_message' for AlertService::TestAlert::Class

generate_message is a method from the MessageTemplate module included in the BaseAlert class. Why is it saying my inherited class doesn't have access to the method?

Upvotes: 0

Views: 99

Answers (1)

tadman
tadman

Reputation: 211670

You're not using Singleton correctly. You're including it, but then not using it, instead bypassing that altogether and calling class methods that have nothing to do with Singleton. They're in turn calling class methods on the parent class that don't exist.

The solution is to use Singleton as intended:

module AlertService
  class BaseAlert
    include MessageTemplate
    include Singleton

    def initialize
    end
  end
end

module AlertService
  class TestAlert < BaseAlert
    def initialize
      @notifier = Slack::Notifier.new(Rails.configuration.url, Rails.configuration.options)
    end

    def create_message
      message = generate_message
    end

    def send_message
      create_message
      @notifier.post blocks: message
    end
  end
end

Where now you call with instance as documented:

AlertService::TestAlert.instance.send_message

Upvotes: 2

Related Questions