Rails not recognizing lib files? - ruby-on-rails

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).

Related

Rails adding external libs to path

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.

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.

Asset Pipeline Cacheing CSS?

I am working on a Rails 3.1 app. I have created an application.css.scss.erb file. The .erb is in the end because I want to load a variable from the config file as the color variable in the css:
$highlight1: #<%= COLOR.highlight1 %>;
$highlight2: #<%= COLOR.highlight2 %>;
Everything works fine, but the problem I am having is that whenever I change a value inside COLOR.highlight1, it doesn't reflect the change until I go in to my css file and change something (i usually add some spaces and save it). Thats when I see the change. Clearly rails is looking to see if the file was changed in order to update the change.
Is there any way that at least during development, this can be turned off and I can see the changes without having to also modify the css file?
Any critique/opinions on my technique are also welcome
The Sprockets depend_on directive is used to declare these kinds of dependencies. So at the top of your css.scss.erb file, with the other directives (require and friends), put something like:
//= depend_on "/path/to/colors.rb"
Then when the file /path/to/colors.rb changes, it will force the css to update too.
Unfortunately, I have never gotten this to work with a relative path to a file outside of one of the asset directories (javascripts/stylesheets/images) so there may be something in the way Sprockets resolves paths that prevents this, or else I'm missing something. That leaves you with the options of specifying an absolute path, which will almost certainly not work in across all your app environments, or putting the constants file into your asset directories (app/assets/stylesheets/colors.rb, for example).
For reference, here's the doc for the depend_on directive from the Sprockets (2.0.3) source, in sprockets/directive_processor.rb
# Allows you to state a dependency on a file without
# including it.
#
# This is used for caching purposes. Any changes made to
# the dependency file will invalidate the cache of the
# source file.
#
# This is useful if you are using ERB and File.read to pull
# in contents from another file.
#
# //= depend_on "foo.png"
#
If anyone does know a way to specify relative paths to other places like config/initializers or something, please let me know!
In addition to David Faber's answer. I needed to use relative paths too.
I wanted to generate a js file with the locale dictionary, which would update if the locale files were changed:
//= depend_on "../../../config/locales/en.yml"
//= depend_on "../../../config/locales/ja.yml"
var locales = <%= locales.to_json %>;
Turns out that currently (Rails 3.2.3) relative paths only work if the relative path is also in the assets path!
So the ugly solution is to add the path in config/application.rb:
config.assets.paths.unshift Rails.root.join("config", "locales").to_s
http://guides.rubyonrails.org/configuring.html
config.assets.compile is a boolean that can be used to turn on live Sprockets compilation in production.
might want to try that, I'm not sure if its getting compiled real time though, at least it should disable the caching.
maybe try:
config.assets.digest = true
in your development config file
I try this, it work
in application.rb
config.autoload_paths += %W(#{config.root}/lib/assets_variables)
config.assets.paths << File.join(Rails.root, 'lib', 'assets_variables')
in lib/assets_variables/color.rb
module Color
def self.default
'blue'
end
end
in app/assets/stylesheets/color.css.scss.erb
//= depend_on "color.rb"
$default_color: <%= Color::default %>;
.content {
color: $default_color;
}

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