dry-rails icon indicating copy to clipboard operation
dry-rails copied to clipboard

Dependency is not registered when namespace is non-standard named

Open deepj opened this issue 5 years ago • 7 comments

Describe the bug

I have a namespace which looks like (example) CloudNATS. This is a namespace of Rails application declared in config/application.rb as well.

When I tried to import a dependecy, I got

Dry::Container::Error (Nothing registered with the key :http)

To Reproduce

# app/operations/create_user
class CreateUser
  include CloudNATS::Import[:http]
end
# lib/cloudnats/http.rb
module CloudNATS
  class HTTP
  end
end

Expected behavior

The dependency is successfully imported without any exception. My namespace would

Your environment

  • Affects my production application: NO
  • Ruby version: 2.7.1
  • OS: macOS

deepj avatar Apr 19 '20 06:04 deepj

This is expected since it's not a regular word that includes an acronym that you need to register in your inflector. I'm not sure if registering just the acronym or the entire word will work, you need to verify that yourself.

solnic avatar Apr 20 '20 08:04 solnic

The acronym is declared in config/initializers/inflections.rb 🤧

deepj avatar Apr 20 '20 08:04 deepj

@deepj yeah but the path to files does not match the constant name, lib/cloudnats/http.rb should be lib/cloud_nats/http.rb. Whatever you do, you need to make sure that the inflector correctly converts the dir names into constant names.

solnic avatar Apr 20 '20 08:04 solnic

@solnic The problem is, at least in my understanding the situation, the Rails' Inflector returns cloudnats for CloudNATS

Loading development environment (Rails 6.0.2.2)
irb(main):001:0> 'CloudNATS'.underscore
=> "cloudnats"

I tried lib/cloud_nats/http.rb as well, but without any success :(

NOTE: The naming of the app was chosen a few years ago btw :)

deepj avatar Apr 21 '20 08:04 deepj

I know why it's happening 🙀

Screenshot 2020-04-21 at 10 52 09

I guess I would update documentation because it's taken from dry-rails documentation 😹

Suggestion, dry-rails may would expose Zeitwerk inflection API. Because after solving the above fix, I'm getting

expected file ~/lib/cloudnats/http.rb to define constant CloudNATS::Http, but didn't (Zeitwerk::NameError). 

And this is dangerous to set in Rails Inflector because it can affect 3rd-party gems which can use HTTP acronym in their names. It's safer to use Zeitwerk inflection rather than Rails one.

deepj avatar Apr 21 '20 09:04 deepj

Suggestion, dry-rails may would expose Zeitwerk inflection API

yeah I've thought about it. In general I would like to make dry-rails zeitwerk-only eventually, because it's a much better solution than whatever old Rails is doing.

solnic avatar Apr 21 '20 11:04 solnic

And this is dangerous to set in Rails Inflector because it can affect 3rd-party gems which can use HTTP acronym in their names. It's safer to use Zeitwerk inflection rather than Rails one.

I should add that you can (and in this case should) set up a custom inflector and configure it to your needs. It's a matter of doing config.inflector = your_inflector

solnic avatar Apr 22 '20 09:04 solnic