Rails adding external libs to path - ruby-on-rails

I'm working on a rails app. I've extracted some common code out into a library under
APP_ROOT/lib/my_lib/my_lib.rb
APP_ROOT/lib/my_lib/version.rb
Currently my controllers can access the lib, but if I write a small standalone script in
APP_ROOT/lib/my_lib/test.rb
that looks like this:
require 'my_lib'
libtest = MyLib.new
I get a error:
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- my_lib (LoadError)
I've tried modifying LOAD_PATH, RUBYLIB to include this, but I can't seem to get it to find the library.

For Rails 3/4 you simply need to update config/application.rb
config.autoload_paths << "#{config.root}/lib/my_lib"

Try this:
require './lib/my_lib/my_lib.rb'

It's your custom lib i.e.
my_lib.rb
and it's in a folder called my_lib. When you try to require a lib like:
require 'name_of _the_lib.rb'
the server looks for the file in the lib folder which is in APP_ROOT. So, now you have to mention your my_lib folder too like this:
require 'my_lib/my_lib.rb'
Hope it will work.

Related

How to require some lib files from anywhere

I'll explain my situation.
Here is my file tree in my rails application :
lib/my_module.rb
require 'my_module/my_file'
module My_module
end
lib/my_module/my_file.rb
class Tweetag::Collector
(...)
end
I've made a ruby script that I've put in config/jobs/
I really don't understand how I am supposed to require the file my_file.rb in this file.
require '../../my_module/my_file.rb'
It gives me `require': cannot load such file
Same error with just require 'my_module' which is what I do in my controllers...
Someone here to explain to me ? Thanks a lot
You can autoinclude everything under the lib folderand avoid these problems:
Type this your file in config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
If you want to require only a specific file then,
do something relative to Rails root like this
for example: --
lib/plan.rb
module Plan
...some code...
end
and if you want to require it only in some model, say app/models/user.rb
do in user model
require "#{Rails.root}/lib/plan"
class User < ActiveRecord::Base
include Plan
end
if you want it to be available everywhere
one solution is given by #VecchiaSpugna
or you can create a ruby file in config/initializers folder
and require all file over there one by one
OR
try this
require '../../my_module/my_file'
instead of
require '../../my_module/my_file.rb'
You don't need to specify extension for a file in require.
I think there are two solutions.
1) Add the lib path to the search path.
In ruby:
$:.unshift('../../my_module/lib')
Then you can require 'my_module.rb'
I think Vecchia Spugna answer is the rails-version of my ruby-answer. (I'm not familiar with rails).
2) Another solution:
In your lib/my_module.rb you require my_file. This file is located relative to your my_module.rb? Then use require_relative:
require_relative './my_module/my_file'
Just chiming in because it took me forever to figure this out because very little solutions worked.
• I had to use plain old require. I put it in the config/application.rb file.
patching_file_path = File.expand_path("./lib", Dir.pwd)
Dir[patching_file_path+'/*.rb'].each {|file| require file }
• I also put a temporary puts "I'm Working! in the file I'm trying to require so I can check the console to see if it's actually loading.
• Also, if you're using spring loader, before you start your console you should do bin/spring stop in your terminal before you start your rails console. Otherwise, it won't load new files.
Similar to require_relative,
# inside lib/my_module.rb
require File.expand_path('./my_module/my_file', File.dirname(__FILE__))
This expands the path of current file directory and add the relative file path to be required.

Using /lib/ Subdirectories in Rails - for View Content

This is an evolving issue related to a previous posting I made...
I am playing around some - to try to learn how the /lib/ directory in Rails works - and how to reference variables defined in the /lib/ directory for use in a view.
I have a file called helloworld.rb and it's saved in a /lib/hellotest/ directory in Rails.
The helloworld.rb file has the following code:
module HelloWorld
def hello
#howdy = "Hello World!"
end
end
I want to be able to display the results of this method on a view called index.html.erb, so I include the following code in the index_helper.erb file:
module IndexHelper
require 'helloworld'
end
I have learned that I need to include the following line of code in the /config/application.rb file:
config.autoload_paths += %W(#{Rails.root}/lib/hellotest/)
Also, I include the following code on the view index.html.erb:
<%= #howdy %>
I think I may have found something that is causing problems. I didn't want to load the entire /lib/ directory at startup so I put the file in a subdirectory called /lib/hellotest/. I've read there are some issues with how Rails interprets module/class naming conventions in the lib folder, but I can't quite figure it out. I see a good resource regarding this possible solution to my problem on William B Harding's Blog, on point 2 - but I can't quite get my arms around this solution as it pertains to my problem.
Any advice please?
What am I missing?
I'd suggest that unless you have a good reason to do otherwise, follow the conventional naming for modules and classes (as described in the link you provided). Rename helloworld.rb to hello_world.rb, move it into lib, and change your autoload_paths to:
config.autoload_paths += %W(#{Rails.root}/lib/)
Finally, change require 'hello_world' to require 'hello_world' in your IndexHelper module. It should then load normally.

Rails not recognizing lib files?

I have a lib/redirect_follower.rb file
Where I use the file, I include it with require 'RedirectFollower'
But rails is playing hard ball with this error:
no such file to load -- RedirectFollower
Any clues? Been banging my head over this for hours. Have tried auto loading all libs using application.rb but that didn't work either.
require is for including a file, not a class.
You need to require "redirect_follower", ie, the actual filename, not the class name. You may also need to add lib to your include path, or require "lib/redirect_follower".
In config/application.rb: add this:
config.autoload_paths << "#{config.root}/lib"
With this setting, your modules (i.e. files under lib/) will be automatically required so you don't have to require them anywhere (actually, you should never require them because that would have an negative effect on un/loading files by Rails).

How do you include a class from /lib into your code in app/controllers

I have a class sitting in /lib folder.
It's in a file called mailing.rb
And I would like to use this class in codes from app/controller.
How do i do this?
Rails 3 no longer automatically loads the files from lib.
In your application.rb file, you can add lib to your autoload_paths:
config.autoload_paths += Dir["#{Rails.root}/lib"]
This way, your mailer.rb and all other files in lib will be available to the rest of your application.
I believe you need to add an initializer file with the require statement in it, for example if your lib file is /lib/some_module.rb you would need to create an initialiser file in /config/initializers/require_libs.rb...
# /config/initializers/require_libs.rb
require 'some_module'

Adding lib to 'config.autoload_paths' in Rails 3 does not autoload my module

I place a file name g.rb in side Rails.root/lib folder
The file content is like this:
module Google
end
Then I add
config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)
to my Rails.root/config/application.rb
However, when I try to invoke Google from rails console, an exception is thrown. The exception goes away only if I execute require 'google'.
Why? Shouldn't my file is autoloaded and shouldn't I access the module without any extra require statement?
Hmm, I discovered an interesting thing. In order for Rails to auto load my class, the class name should be compliant to the file name and the folder structure.
For example, if I want to have Google module autoloaded, I must placed it inside google.rb, directly under /lib (incase I specify autoload from /lib).
If I want to auto load Google::Docs, then I either place it inside google.rb or google/docs.rb
I had a similar problem with getting my module to run on Heroku. In addition to the autoload naming convention stated by Stephen C, I found out that the module code must be require'd due to a threadsafe assumption made by the Rails' production environment on Heroku (even though threadsafe was commented out in my production.rb configuration file.) As soon as I require'd the module file before calling include on the module, everything started to work.
require 'mymodule'
include Mymodule
Please take a look at this excellent article on the subject of getting Modules to load correctly in Heroku (production).
That's because the point of autoload is not to 'require' everything up front (startup penalty). Classes are loaded as they are needed/referenced. In order to do this, you need some way to know where to look for the class. Otherwise, you would have to load every file in the autoload directory in advance to see what classes are declared. It's a tradeoff, but requiring everything in advance (as marbaq suggests) is not autoloading.
You can use the autoload command as provided by Ruby, which takes two arguments, the module to load (symbolized, i.e. :Google in your case), and the second argument is the filename, which would be g.rb if lib is in your load path ($:). See the Ruby docs for autoload.
Change config.autoload_paths to config.eager_load_paths
(based on Rails issue #6850 and Force reload! from lib directory in rails 3.2 console)
I faced the same problem just now, and my "solution" (or rather workaround) was to manually require every needed file from Rails.root/lib in my application.rb.
require 'lib/message'
require 'lib/store'
require 'lib/vault/vault.rb'
require 'lib/custom_loggers'
module MyApplication
class Application < Rails::Application
My next step would be to categorize the files in module folders as you mention.
i found this solution recently
config/application.rb
module AppName
class Application < Rails::Application
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
config.autoload_paths += Dir[Rails.root.join('app', 'lib', 'extensions')]
end
end
the first config call induces rails to auto-load all sub-directories of the app/models directory
so now i can have /app/models/sub_directory/model.rb auto-loaded
(handy for organising an app with a large code base)
the second config call induces rails to autoload the lib/extensions directory
hope this helps
note: i believe this is rails 3 specific

Resources