admin管理员组文章数量:1296461
I have a Rails folder with two files:
app/hub_spot/client.rb:
module HubSpot
class Client
app/hub_spot/create_contact_form.rb:
module HubSpot
class CreateContactForm
when I run the zeitwerk check I get:
expected file app/hub_spot/client.rb to define constant Client, but didn't
if I add:
config.autoload_paths << Rails.root.join("app/hub_spot")
config.eager_load_paths << Rails.root.join("app/hub_spot")
then I get a new error:
expected file app/hub_spot/create_contact_form.rb to define constant CreateContactForm, but didn't
it seems to complain about both files differently? Any way to tell Zeitwerk to look at the folder for the module name?
I have a Rails folder with two files:
app/hub_spot/client.rb:
module HubSpot
class Client
app/hub_spot/create_contact_form.rb:
module HubSpot
class CreateContactForm
when I run the zeitwerk check I get:
expected file app/hub_spot/client.rb to define constant Client, but didn't
if I add:
config.autoload_paths << Rails.root.join("app/hub_spot")
config.eager_load_paths << Rails.root.join("app/hub_spot")
then I get a new error:
expected file app/hub_spot/create_contact_form.rb to define constant CreateContactForm, but didn't
it seems to complain about both files differently? Any way to tell Zeitwerk to look at the folder for the module name?
Share Improve this question asked Feb 12 at 6:16 amclellandamclelland 294 bronze badges 1 |2 Answers
Reset to default 2Rails uses a pretty quirky autoloader setup for historical/lazyness reasons. It's really more oriented around just anizing top level constants by purpose than pesky stuff like encapsulation.
Every subdirectory of the app
directory is automatically added as an root directory in Zeitwerk. Root directories are where Zeitwork expects top level constants to be found and are ignored when resolving a file path into a constant. Rails still uses the terms autoloading_paths
and eager_load_paths
which is a holdover from the classic autoloader used up until Rails 6 which are roughly equivilent.
Thus if you move your file into app/foo/hub_spot/client.rb
Zeitwork will have no problem finding it. Note that the name of the root level folder is actually inconsequential (except for us humans).
You can compare this to the typical gem setup which just has a single root directory (lib
) and where the code is expected to be nested in module and folder with the name of the gem.
Any way to tell Zeitwerk to look at the folder for the module name?
While you could add the app
directory itself as an autoloading root I would be wary of potential bugs.
Really the only reason for putting code in app
(except the expectation of other developers) is that you want to use the Rails autoloader setup so just embrace the wierdness and add another level of directory nesting so it's at least consistently wierd.
You could also just setup Zeitwerk to load your code from lib/my_namespace
to mirror how gems are setup (which is a lot less quirky).
it seems to complain about both files differently?
It doesn't. It's telling you that it expects the constants to be defined at the top level as the file path from it's perspective is just /create_contact_form.rb
. It's just checking different files.
config.autoload_paths << Rails.root.join("app/hub_spot")
is completely redundant as that happens by default anyways.
See:
- https://github/fxn/zeitwerk
- https://guides.rubyonrails./autoloading_and_reloading_constants.html
Fix the Namespacing Problem Your current situation:
app/hub_spot/client.rb app/hub_spot/create_contact_form.rb
These files are within app/hub_spot/, so Zeitwerk will expect them within the HubSpot module. But Zeitwerk doesn't deduce the HubSpot module from the folder name itself—you must specify it explicitly.
Solution: Rearrange the File Structure or Module Definitions Option 1: Move the Folder into app/lib/ or app/models/ Zeitwerk loads directories in app/ (such as models, controllers, etc.) automatically, but app/hub_spot/ is not one of them by default.
Instead, place your folder within app/lib/hub_spot/ and include:
本文标签: ruby on railsZeitwerk error expected to define constantStack Overflow
版权声明:本文标题:ruby on rails - Zeitwerk error: expected to define constant - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741618415a2388666.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
module Models
underapp/models
. same thing applies toapp/hub_spot
. you need to add an extra directoryapp/something/hub_spot
stackoverflow/a/78830222/207090 – Alex Commented Feb 12 at 6:33