Rails Grape API include module - Zeitwerk::NameError - expected file to define constant, but didn't:

1.9k views Asked by At

I want to make a small code refactor and extract client external client from gem to a separate module (it's use to connect to the DatoCMS API via gem 'dato'). My standard class, which works well, look like:

app/services/receive_webhook/fetch_model_name.rb

module ReceiveWebhook
  class FetchModelName
    def initialize(model_id)
      @model_id = model_id
    end

    def call
      fetch_model(@model_id).dig('name')
    end

    private

    def client
      @client ||= Dato::Site::Client.new(Rails.application.credentials.datocms_api_token)
    end

    def fetch_model(model_id)
      client.item_types.find(model_id)
    end
  end
end

I want to separate client method to a different module and include it in FetchModelName class (like in standard Rails app). To do so I use below code:

app/dato_cms_api/dato_client.rb

module DatoCmsApi
  module DatoClient
    def client
      @client ||= Dato::Site::Client.new(Rails.application.credentials.datocms_api_token)
    end
  end
end

With updated FetchModelName class: app/services/receive_webhook/fetch_model_name.rb

module ReceiveWebhook
  class FetchModelName
    include ::DatoClient

    def initialize(model_id)
      @model_id = model_id
    end

    def call
      fetch_model(@model_id).dig('name')
    end

    private

    def fetch_model(model_id)
      client.item_types.find(model_id)
    end
  end
end

But I'm getting an error:

Zeitwerk::NameError - expected file app/dato_cms_api/dato_client.rb to define constant DatoClient, but didn't:
  app/services/receive_webhook/fetch_model_name.rb:5:in `<class:FetchModelName>'
  app/services/receive_webhook/fetch_model_name.rb:4:in `<module:ReceiveWebhook>'
  app/services/receive_webhook/fetch_model_name.rb:3:in `<main>'
  app/controllers/api/v1/webhooks/dato_cms/receive_webhook.rb:29:in `block in <class:ReceiveWebhook>'

Does Grape API not support include module practice?

1

There are 1 answers

0
DinhNgocHien On

Did you try to downgrade your autoloader to classic? In your application.rb file, add this:

config.autoloader = :classic