0
votes

The ruby global variable $: shows you what's in the load path. When I look at the load path of my rails application, I immediately notice the lib directory in the Rails root is in it:

puts $:
/Users/myuser/projects/myproject/lib
/Users/myuser/projects/myproject/app/assets
/Users/myuser/projects/myproject/app/controllers
/Users/myuser/projects/myproject/app/helpers
/Users/myuser/projects/myproject/app/mailers
/Users/myuser/projects/myproject/app/models
...

I added a file named my_module.rb and it includes a module MyModule. I stick in a method called hello_world which puts 'hello world'. Now, when I include the module in a rails model, like this:

class MyModel < ActiveRecord::Base
  include MyModule
end

And then I fire up the console:

2.1.2 :001 > m = MyModel.new
NameError: uninitialized constant MyModel::MyModule

Ruby cannot find the MyModel source file. In order tog et this to work, I have to explicitly require it:

class MyModel < ActiveRecord::Base
  require 'my_module'
  include MyModule
end

Now things work:

2.1.2 :001 > m = MyModel.new
2.1.2 :001 > b.hello_world
2.1.2 :001 > hello world
2.1.2 :001 > => nil 

Since lib is already in the load path, why must I still explicitly require MyModule? And how does rails get away with not having to use require all over the place?

1

1 Answers

1
votes

$: or $LOAD_PATH variable contains list of paths in which Ruby would be search the files required by the module or class. Only search and doesn't 'include' them, so you must care of it by yourself.

Rails has autoload feature and you can define it in config/appliaction.rb file or in environment-specific (config/enviroments/development.rb). Here you have more informations. You can add something like this:

config.autoload_paths += %W(#{config.root}/lib)

After that you could include the model without require command.

Additional resources:

telladifferentstory

blogarkency