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

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.

Related

compass-rails within a rails engine

I am trying to make a rails engine use the sprite generation capabilities of compass.
I added compass-rails to the main app's Gemfile (outside the assets group).
In the engine's CSS file I do:
#import "my-engine/icons/*.png";
#include all-icons-sprites;
Alas, the app looks for images at the wrong dir
ActionView::Template::Error (No files were found in the load path matching "my-engine/icons/*.png". Your current load paths are: /home/dan/work/main-project/app/assets/images
(in /home/dan/work/my-engine/app/assets/stylesheets/my-engine/sources.css.scss)):
How and where should I configure compass to look in the right path?
2 things to check:
The compass plugin looks in the app/assets/images folder for content.
Files need to have a PNG extension only.
Update for comments
If you would like to save the images elsewhere in your application, for example 'public/sprites', you can specify the follow config setting in your config/application.rb:
config.compass.generated_images_dir = 'public/sprites'
Furthermore, since the new sprite file is being saved in 'public/sprites/icons-xxx.png', you will need to add the output path to the assets path in your config/application.rb:
config.assets.paths << Rails.root.join('public', 'sprites')

Excluding files from assets:precompile in rails

I use codekit for writing less which it then converts to css automatically.
I don't want rails to convert my less files to css, I rather codekit do it.
if I precompile the assets via
rake assets:precompile
I get
rake aborted!
cannot load such file -- less
How do I exclude a specific folder/file types from precompiling? (all my less files are in app/assets/stylesheets/less and the css (which I do want to be precompiled) are in app/assets/stylesheets/css
update
deleting application.less solves this but how do I excluding it from processing in the first place?
From the Asset Pipeline guide:
The default matcher for compiling files includes application.js,
application.css and all non-JS/CSS files (i.e., .coffee and .scss
files are not automatically included as they compile to JS/CSS):
[ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, /application.(css|js)$/ ]
If you have other manifests or individual stylesheets and JavaScript
files to include, you can add them to the precompile array:
config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
So, I would say that your solution is to modify config.assets.precompile to exclude .less files. Maybe something like this (in a suitable environment file, like config/environments/production.rb):
config.assets.precompile = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css', '.less']) }, /application.(css|js)$/ ]
If your directory structure under the app/assets folder is so:
application.css
/css
(generated by code kit)
|...home.css
|...index.css
/less
|...home.less (assuming this is the extension)
|...index.less
Then, in your application.css file, there must be a directive that says *= require_tree . This tells rails to scan all the files/directories and try to compile all the files into one css file.
Change this to *= require_directory ./css and it will load the files under the css directory for compilation.

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.1 customize sprockets precompile assets

I am trying to customize what assets get precompiled. In production I only want application.js and applicaiton.css to be compiled and not all the subsequent files that are included.
For example giving the following files I only want one file (appliation.css) to be output when I run the precompile rake task
##application.css
//include components/form.elements
//include components/lists
The default is to precompile all assets in the assets directory and it is quite messy.
EDIT correction it is the default to precompile all non js and css files in the assets directory. If however you have a file like form.elements.js sprockets will precompile it thinking it is a non js/css file.
Check the sprockets documentation, it is quite extensive and well-written.
For your particular problem, the following application.css would only include the components/form_elements and components/lists directories, recursively:
/*
*= require_tree components/form_elements
*= require_tree components/lists
*/
If form_elements and lists are css files, just replace require_tree with require.
The default precompile options work as long as you don't have any files with extra periods in them. like (jquery.treeview.js)
I was able to to get my assets to compile the way I wanted by explicitly defining the individual files that I wanted compiled.
config.assets.precompile = [ 'application.css' ]
now in the public assets folder there is only one file that includes all the suplemental file content minimized.
EDIT
Rails default precomplie option has been changed to
[ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, /application.(css|js)$/ ]
so files with extra periods will compile properly now

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.