From 07d7b8f58c63ddc55b005daeb0910d31970b3d88 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sat, 16 Nov 2019 00:06:14 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- doc/development/gotchas.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'doc/development/gotchas.md') diff --git a/doc/development/gotchas.md b/doc/development/gotchas.md index c7eed880554..da27ae9110b 100644 --- a/doc/development/gotchas.md +++ b/doc/development/gotchas.md @@ -168,3 +168,73 @@ in an initializer._ ### Further reading - Stack Overflow: [Why you should not write inline JavaScript](https://softwareengineering.stackexchange.com/questions/86589/why-should-i-avoid-inline-scripting) + +## Auto loading + +Rails auto-loading on `development` differs from the load policy in the `production` environment. +In development mode, `config.eager_load` is set to `false`, which means classes +are loaded as needed. With the classic Rails autoloader, it is known that this can lead to +[Rails resolving the wrong class](https://guides.rubyonrails.org/v5.2/autoloading_and_reloading_constants.html#when-constants-aren-t-missed-relative-references) +if the class name is ambiguous. This can be fixed by specifying the complete namespace to the class. + +### Error prone example + +```ruby +# app/controllers/application_controller.rb +class ApplicationController < ActionController::Base + ... +end + +# app/controllers/projects/application_controller.rb +class Projects::ApplicationController < ApplicationController + ... + private + + def project + ... + end +end + +# app/controllers/projects/submodule/some_controller.rb +module Projects + module Submodule + class SomeController < ApplicationController + def index + @some_id = project.id + end + end + end +end +``` + +In this case, if for any reason the top level `ApplicationController` +is loaded but `Projects::ApplicationController` is not, `ApplicationController` +would be resolved to `::ApplicationController` and then the `project` method will +be undefined and we will get an error. + +#### Solution + +```ruby +# app/controllers/projects/submodule/some_controller.rb +module Projects + module Submodule + class SomeController < Projects::ApplicationController + def index + @some_id = project.id + end + end + end +end +``` + +By specifying `Projects::`, we tell Rails exactly what class we are referring +to and we would avoid the issue. + +NOTE: **Note:** +This problem will disappear as soon as we upgrade to Rails 6 and use the Zeitwerk autoloader. + +### Further reading + +- Rails Guides: [Autoloading and Reloading Constants (Classic Mode)](https://guides.rubyonrails.org/autoloading_and_reloading_constants_classic_mode.html) +- Ruby Constant lookup: [Everything you ever wanted to know about constant lookup in Ruby](http://cirw.in/blog/constant-lookup) +- Rails 6 and Zeitwerk autoloader: [Understanding Zeitwerk in Rails 6](https://medium.com/cedarcode/understanding-zeitwerk-in-rails-6-f168a9f09a1f) -- cgit v1.2.3