问题
I'm having a class Dog
in app/models/dog.rb
and another class Services::My::Deeply::Nested::Dog
in app/services/my/deeply/nested/dog.rb
.
Now in Services::My (app/services/my.rb), I have a reference to one of the following (no need to distinguish, since the behaviour is exaclty the same in all situations):
Deeply::Nested::Dog
Services::My::Deeply::Nested::Dog
::Services::My::Deeply::Nested::Dog
No matter which of the above I choose, I always get the following error message:
services/my.rb: warning: toplevel constant Dog referenced by
Services::My::Deeply::Nested::Dog
Also, my deeply nested Dog never even gets seen by the interpreter (I found out by using puts and syntax errors, nothing happens).
Possible workarounds (which I all don't like) are:
- Rename one of the Dog classes
- Run with RAILS_ENV=production in order to disable autoloading and use eager loading instead
require_dependency
that points to the deeply nested dog
As a computer scientist, I find none of the above workarounds satisfactory. I would like to understand why my deeply nested Dog is not found without workaround and find out what the state-of-the-art Ruby / Rails solution would be for this problem.
Thanks a lot in advance.
回答1:
app/services/my/deeply/nested/dog.rb
should define My::Deeply::Nested::Dog
and not Services::My::Deeply::Nested::Dog
, for the same reason that app/models/dog.rb
doesn't define Models::Dog
but just Dog
.
With :
#app/services/my/deeply/nested/dog.rb
module My
module Deeply
module Nested
class Dog
puts "I'm in %s" % __FILE__
puts Module.nesting.inspect
end
end
end
end
and
# app/models/dog.rb
class Dog
puts "I'm in %s" % __FILE__
puts Module.nesting.inspect
end
and
# app/services/my.rb
module My
puts "I'm in %s" % __FILE__
puts Module.nesting.inspect
Dog
My::Deeply::Nested::Dog
end
You get :
Loading development environment (Rails 5.0.0.1)
2.3.1 :001 > My
I'm in /home/ricou/www/new_rails_5_app/app/services/my.rb
[My]
I'm in /home/ricou/www/new_rails_5_app/app/models/dog.rb
[Dog]
I'm in /home/ricou/www/new_rails_5_app/app/services/my/deeply/nested/dog.rb
[My::Deeply::Nested::Dog, My::Deeply::Nested, My::Deeply, My]
=> My
来源:https://stackoverflow.com/questions/40928631/name-clash-with-top-level-constant-when-autoloading-with-rails