# app/models/campaign.rb
class Campaign; end # This class is completely irrelevent to our code, but has same class name as the other campaign class.
# app/resources/homepage/apple.rb
module Resources
module Homepage
class Apple < Campaign
campaign_method! # This fails because apple.rb is loaded alphabetically before resources/homepage/campaign.rb
end
end
end
# app/resources/homepage/campaign.rb
module Resources
module Homepage
class Campaign
def self.campaign_method!
"I should be callable"
end
end
end
end
# app/resources/homepage/yolo.rb
module Resources
module Homepage
class Yolo < Resources::Homepage::Campaign
campaign_method! # This works because the parent class is unambiguous
end
end
end
# app/resources/homepage/zolo.rb
module Resources
module Homepage
class Zolo < Campaign
campaign_method! # This works by luck, because Zolo is loaded alphabetically after resources/homepage/campaign.rb
end
end
end
I was able to debug this issue using rails console
pry(main)> Resources::Homepage::Yolo # returns a constant
=> Resources::Homepage::Yolo
pry(main)> Resources::Homepage::Apple # returns an error message
NameError: undefined local variable or method `campaign_method!' for Resources::Homepage::Apple:Class`
After changing class Apple < Campaign
to class Apple < Resources::Homepage::Campaign
and reloading the console, the code loads correctly.
Explicitly loading the required file also works, which is what Rails AutoLoader (usually) does correctly for you. The Rails Guides discourages using require
or require_relative
for auto loaded files. Instead use require_dependency
# resources/homepage/apple.rb
require_dependency 'resources/homepage/campaign'
module Resources
module Homepage
class Apple < Campaign
campaign_method! # this works and loads campaign's class method
end
end
end
Nice writeup. Yeah, Rails’ autoloading of constants is weird magic, and most Rails developers (including myself) don’t really understand how it works and what the consequences of it are, which causes many subtle bugs to be created.
In general, for all kinds of library "magic": everything it does for you it also does to you