Why can't Rails 3.2.9 automatically require a *.rb file in the "lib" directory? - ruby-on-rails-3

I realize that "lib" is no longer autoloaded by default. However, I have this in my application.rb file:
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/datatables)
I have a module in lib called utility.rb, declared as follows:
module MyApp
module Utility
I have some utility methods in there, for example a method that takes an array and turns it into values that can be queried from MySQL. I have:
include MyApp
at the top of the classes that need that method, so that I can then just call:
Utility::array_to_query_string
Unfortunately, this does not work. Whether running a rake task or the application, I am met with:
uninitialized constant MyApp
I don't know how to make Rails require other than what I have above. In the console, if I explicitly type require 'utility' and then I can successfully do the include. What do I have to do to make Rails autoload this module?

The problem could be the directory structure in your lib folder. That the rails autoloader can find your file, it needs to be placed in the right spot. Your MyApp::Utility module should live in a file called: lib/my_app/utility.rb.
If you place the file directly in lib lib/utility.rb the autoloader won't find it.

In some of my apps, I add an initializer that loads my custom code.
In config/initializers/utility.rb,
require "#{Rails.root}/lib/utility"

Related

Rails Constants using Initializers

I'm not sure what I'm doing wrong. I am written a module in a file: config/initalizers/constants.rb
I have a defined a module with a constant and a static method. It's accessible when called in a view. The problem occurs when I want to call the method from in one of the environment files where I get an unitialized constant error. I believe the initializers are being run after the environment files are being loaded but I am not sure where best to place the method or file.
Any help would be appreciated.
This may be solved by saving the constant as an environment variable instead. For development I can recommend the Dotenv gem. Of course it would need to be added to the production server environement as well, but Heroku etc make this very easy.
You add something like CONSTANT_NAME=stringofcharacters1234 in a newly created .env file in the root rails directory and everytime you start up rails s it will parse that file and make those variables accessible to you through the ENV hash where you can access it like ENV["CONSTANT_NAME"] wherever it's needed.
I also prefer using ENV.fetch("CONSTANT_NAME") because this will raise an error if it's empty, helping in debugging if something fails because of an empty env variable.
Hope this is what you're looking for!

config.assets.precompile - include a folder of files? or kill the precompile 'feature' entirely?

I have read and tried the Assets Pipeline guide here:
http://guides.rubyonrails.org/asset_pipeline.html
... which shows how to include specific files in a manually created and updated list, --OR-- the Proc which includes a directory (or directories) but then excludes all the other files which Rails ordinarily includes.
I want to += my folder of files to the normally included files.
I have tried the answers:
Rails config.assets.precompile setting to process all CSS and JS files in app/assets
What is the purpose of config.assets.precompile?
rails config.assets.precompile for specific sub folder
... the last of which appears to show a solution:
config.assets.precompile += ["*external/calendars*"]
which I changed to:
config.assets.precompile += %w["*javascript*"]
or
config.assets.precompile += ["javascript"]
(and about 20 other variations.)
... to get my assets/javascript folder. But the directory is not included, as evidenced by the error "...isn't precompiled."
The third method, is to give it
config.assets.precompile += %w( *.js )
... which works, but leads to a very, very long compile, I would assume finding every JS file it can discover, anywhere.
Needless to say, adding files to a manually updated list is not suitable for an in-progress application - and losing whatever unknown things Rails precompiles with an exclusionary Proc won't cut it either (yet those are the only two examples in the docs).
Is there not a simple wildcard solution to "+-=" a folder - or perhaps to just turn this 'feature' off, specify my JS per view, and still have it work on Heroku?
----EDIT - It gets more irrational the deeper I look.
Essentially, the solution is, "Load all the things Rails finds A-OK in Development Mode." And yet such an option does not exist?
The production.rb file, referring to the precompile line, says:
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
... and application.js has:
//= require_tree .
... so that should load all the files under that directory - but it doesn't. Why? The deeper I dig, the less sense this makes.
A good practice when dealing with multiple CSS/JS files to add to the asset pipeline is to simply create a new manifest for those files:
Let's say you have some JS files under lib/assets/javascripts/external/calendars and you want to load them through the asset pipeline.
You want to create an index.js manifest file with the following content:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require_tree .
This way all JS files you add into the external/calendars directory will be included by default thanks to the require_tree . directive.
Now, in your app/assets/javascripts/application.js file add the following line:
//= require calendars
This should find your "calendars' manifest index file" and load all dependent JS files. No need to add anything into the asset pipeline, it will just work.

#import "compass" breaking in asset pipeline rails 3.2.1

I have an application.sass inside app/assets/stylesheets and it has in it:
#import "compass"
When I attempt to launch my development webserver, I get:
Error compiling CSS Asset
Sass::SyntaxError: File to import not found or unreadable: compass.
I am using compass-rails-1.0.0.rc.2 with compass-0.12.rc.1
This probably isn't your problem, but I just ran across the same error message and spent WAY too long trying different versions of compass/compass-rails, thinking it wasn't my fault.
The problem turned out to be that my application.css file wasn't getting run through the sass preprocessor. So I renamed it to application.css.scss and bang! Yours is named .sass, you could check by renaming it to .css.sass, or .css.scss (just to test) and see if you get different results.
Are you upgrading from a pre-asset pipeline version of Rails (e.g. 3.0)? Please make sure that you are requiring the assets group when initializing bundler in your application.rb.
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
Otherwise, for compass to work in development, compass-rails and sass-rails must be outside of the assets group in your Gemfile.

writing tests for modules in lib folder

I want to write unit tests for a module file I created and put it in lib directory. Under test/unit directory, I have created a mylib_test.rb file. In the file I have required mylib. When I run rake test:units it gives a const_missing: uninitialized constant mylib::constantname error. I'm thinking that this is because it is not loading the rails environment since the constant is defined in one of the initializers file. I'm I correct? How do I get it to work? What is the best way to write unit tests for modules?
I'm using rails 3.1.3 and the model works perfectly when I run the application both from terminal and from a browser.
I just ran into this as well. There are (at least?) 2 possible problems:
Your module is not in the autoload path
Look in config/application.rb for this line:
config.autoload_paths += %W(#{config.root}/extras)
If it's commented, uncomment it. This line will turn on autoloading for all files inside extras, and all files in subdirectories of extras, too. It's probably safest to move your modules into extras, but if you really want to leave them in lib, change the line to be:
config.autoload_paths += %W(#{config.root}/extras #{config.root}/lib)
Your module is in the autoload path, but not named the way Rails expects
(see this: Rails 2.3.5: How does one access code inside of lib/directory/file.rb?)
By convention, Rails wants the name of your module to match the directory hierarchy and the filename. So the file extras/mylib.rb would be expected to contain
module Mylib # not MyLib or My_lib
...
end
This works for subdirectories as well, so a file extras/mydir/mylib.rb should contain:
module Mydir
module Mylib # or class Mylib
...
end
end
This naming convention is the same as what Rails expects for controllers and models. Underscores in the filename turn into a camelcase class/module name. A file called my_lib.rb would be expected to have a module MyLib in it (but not Mylib).
NOTE that autoload does not mean that the module is automatically loaded at startup; rather, it's automatically loaded when it's first used. So even if you have some code like puts "hi from mylib" at the top of your mylib.rb file, you won't see that print until your code uses Mylib somewhere.
Finally, if you really want your modules to load at startup, go create a file called config/initializers/force_load_libraries.rb and put this in there:
Dir.glob("#{Rails.root}/extras/force_load/*.rb").each { |f| require f }
Now go put your libs in extras/force_load and they should load when Rails starts up.
I finally realized what was wrong. In my test files, I was including my modules from the lib directory, Instead of reopening the module and put the test files in the the module. After doing that rake test:units works perfectly. Test files should remain in test/unit directory

rails 3 sass compiling

Hello I have one question I have my file main.scss which is in public/stylesheets/scss. In documentation is written:
By default, .sass and .scss files are
placed in public/stylesheets/sass
(this can be customized with the
:template_location option). Then,
whenever necessary, they’re compiled
into corresponding CSS files in
public/stylesheets. For instance,
public/stylesheets/sass/main.scss
would be compiled to
public/stylesheets/main.css.
I have in my gemfile gem 'haml'
And from my view I do sth like this
= stylesheet_link_tag 'main'
And the file is not found when I check the source(there is a file with with information about routing error). I guess that compiling it by hand it is not way to go so how I can make compile scss file to public/stylesheets automatic? What mean in documentation that they are compiled when necessary?
Thanks in advance
Put your .sass or .scss files in public/stylesheets/sass, not public/stylesheets/scss. Then the stylesheets should automatically generate whenever you change the corresponding sass/scss file. The generated stylesheets end up in public/stylesheets/.
Renaming the folder should make it all work.
EDIT: it looks like Rails 3.1 is going to be not only including SASS by default, but it will also be moving most of the stuff found in the public folder to the app folder... so this answer will only apply to versions of rails before 3.1.