Reputation: 559
Context of the Problem
gem 'leanpirates-aarrr', '~> 0.1.1', :path => "/src/gem-aarrr"
runs okrails g
shows the generator lean_pirates:aarrr:install
config/initializers/leanpirates_aarrr.rb
The initializer: leanpirates_aarrr.rb
LeanPirates::Aarrr.configure do |config|
config.api_server = "http://localhost:3000"
config.startup_key = Rails.configuration.leanpirates_aarrr.startup_key
config.startup_secret = Rails.application.secrets.leanpirates_startup_secret
end
The gem definition file: aarrr.rb
# (...)
module LeanPirates
module Aarrr
class << self
attr_writer :configuration
end
def self.configuration
@configuration ||= LeanPirates::Aarrr::Domain::Configuration.new
end
def self.reset
@configuration = LeanPirates::Aarrr::Domain::Configuration.new
end
def self.configure
yield(configuration)
end
end
end
The error
/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in <top (required)>: undefined method 'configure' for LeanPirates::Aarrr:Module (NoMethodError)
/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in `<top (required)>': undefined method `configure' for LeanPirates::Aarrr:Module (NoMethodError)
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `block in load'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:259:in `load_dependency'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
(...)
This is for the opensource LeanPirates AARRR from https://github.com/lean-pirates/gem-aarrr/tree/simplification (branch simplification
)
Upvotes: 3
Views: 2021
Reputation: 559
Problem solved
@tadman guided me in the right direction with his explanation (thanks very much for that), although the problem was bigger than I could initially assess.
The Rails Autoloader was having trouble to load my files. Why? Because I tried to organise them.
The problem was
Namespacing! Long ago, when the gem was started, it felt reasonable to move everything into a /lib/gem folder. However, it proved to be the source of the problem.
With the namespacing not matching the folder structure properly, the Autoloader was having trouble loading the files, and they were not getting recognised along with the classes of my gem, etc.
How was the Namespacing sorted?
When you are doing your gems, make sure that you understand well namespacing. In my case, generating the plugin with the following command line sorted out the problem:
rails plugin new lean_pirates-aarrr
This line above created things in the way they should be for the auto-loader to pick up. It's not something we can complain about: Rails follows a lot the "convention over convention" paradigm.
My end structure was the following: (https://github.com/lean-pirates/gem-aarrr/tree/simplification)
- lib/
-> generators/
-> lean_pirates/
-> aarrr/
-> install/
-> routines/*.rb
-> templates/*.rb
-> *.rb
-> lean_pirates/
-> aarrr/
-> domain/*.rb
-> helpers/*.rb
-> *.rb
I'd be happier to make /generators and /gem at the root, and I'm sure it would be possible, but I don't really wanna fight the convention, so I'm pretty happy to leave it as is, at least for now.
If you are facing the same problem, fixing the folder structure might help the Autoloader to find your files. Change it, or configure it accordingly.
Upvotes: 1
Reputation: 211570
The Autoloader feature in Rails is very handy, it takes care of a ton of things automagically, but it's also not very smart. If a namespace is already defined it will not load additional files.
It's your obligation as a gem to require any and all support modules or classes that are necessary for your library to work properly.
Here's the problem in lib/gem/aarrr/version.rb
:
module LeanPirates
module Aarrr
VERSION = '0.1.1'
end
end
Now LeanPirates::Aarrr
is already defined so no additional work by the autoloader is required. As such, your lib/gem/aarrr.rb
is never loaded.
To fix this you need to avoid creating that namespace path. You should also ensure that require_paths
is set properly in your .gemspec
file so that lib/gem
is referenced correctly. Right now you'd have to require 'gem/aarrr'
which is really confusing and clunky.
I usually set up a plain-old VERSION
file in the main gem directory that has nothing but the version string. The gemspec
can read this in on-demand if required with File.read
, or you can bake it into the .gemspec
using a rake task. I prefer the latter approach as making a .gemspec
with tons of arbitrary code in it is always over-complicating things.
Upvotes: 1