I'm new to Rails and I'm trying to create a custom logger. I've placed my custom logger class in app/custom_logger/custom_log.rb
as follows:
module CustomLogger
class CustomLog
def self.info
puts 'called'
end
end
end
In my AccountController
(app/controllers/account_controller.rb
), I'm trying to use this custom logger:
class AccountController < ApplicationController
def get
CustomLogger::CustomLog.info
render status: :ok
end
end
However, when I send a request to this controller, I get the following error:
uninitialized constant AccountController::CustomLogger
I tried adding include CustomLogger
in app/controllers/application_controller.rb
and using require_relative '../custom_logger/custom_log.rb'
, but neither of these approaches worked.
With this file structure app/custom_logger/custom_log.rb
, zeitwerk is expecting you to define CustomLog
:
# root directory
# |
# vvvvvvvvvvvvvvvvv
# app/custom_logger/custom_log.rb
# ^^^^^^^^^^
# |
class CustomLog # -----'
end
File structure have to correspond to module/class names relative to a root directory. Rails will automatically configure any directory directly under app
to be a root directory by adding it to autoload_paths
.
If you want to have CustomLogger::CustomLog
then you need to make an extra directory under app, name it whatever you like:
# root directory
# |
# vvvvvvvvvvv
# app/loggers/custom_logger/custom_log.rb
# ^^^^^^^^^^^^^ ^^^^^^^^^^
# | |
module CustomLogger # -' |
class CustomLog # ----------'
end
end
https://guides.rubyonrails.org/autoloading_and_reloading_constants.html
Note, that you cannot use this logger when application is booting up, that goes for all reloadable code (everything in autoload_paths
). You could set up autoload_once_paths
if you want to use it in an initializer, or you can always put it in your lib
directory and require
it.