Rails 3.2.2
When running rake assets:precompile I get the following error:
uninitialized constant Redirect
Redirect is a custom middleware class that redirects naked domain requests from mydomain.com to www.mydomain.com.
I load the middleware in production.rb using:
config.middleware.use Redirect
The redirect.rb is located at lib/middleware/redirect.rb. I load the path in application.rb using:
config.autoload_paths += %W(#{config.root}/lib/middleware)
It works fine when you run the application, and other rake tasks run fine. But running rake assets:precompile appears to not load the lib properly. I first noticed the issue running on Heroku, but I've been able to reproduce locally no problem.
Any ideas? Thanks!
You probably have config.assets.initialize_on_precompile = false set somewhere.
I experienced this error after setting that configuration for something related to Heroku. To fix, i just require "#{Rails.root}/lib/my_middleware.rb" right above the line where I configure the app to use the middleware.
I was getting the same error for loading a class from /lib and assigning it to a ::GLOBAL variable.
This was because I had forgotten to place it inside an after_initialize block, which is how I had done it in development.
config.after_initialize do
::GLOBAL = MyLib::MyClass.new
end
Hope this helps somebody!
Related
I have a Rails 5 application with some modules/classes located under /lib. In development I can access those through the rails console like so:
irb(main):001:0> MyClass.do_something
In Production on Heroku I get this:
irb(main):001:0> MyClass.do_something
NameError: uninitialized constant MyClass
As you might have guessed I autoload the /lib directory in my application.rb:
config.autoload_paths << Rails.root.join('lib')
However, the most curious thing about this is, that I can access this class from rake tasks. So something like this works fine:
task do_something: :environment do
MyClass.do_something
end
Which tells me that the class is present on Heroku.
Any ideas?
Rails doesn't autoload in production for thread safety, instead eager loading application constants. You can fix your issue by using the eager_load_paths method instead.
config.eager_load_paths << Rails.root.join('lib')
If you still want to autoload in development you can make it conditional
load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
config.public_send(load_path_strategy) << Rails.root.join('lib')
If you really need autoloading of this directory in production you can set enable_dependency_loading to true.
config.enable_dependency_loading = true
config.autoload_paths << Rails.root.join('lib')
See this blog post for more explanation.
I have been puzzled why all of my objects were uninitialized constant in console on heroku in production. In my local production, they were fine.
Turns out that the problem was that I was running: "heroku run console" not "heroku run rails console".
Worth noting that when you access console from the heroku website, the same problem occurs there too. Wasted a lot of time on this.
I was having issues deploying my project to a heroku server (Precompile fail). So I found this response, https://stackoverflow.com/a/13713753/2989437, and followed up on the advice. I added one line to my application.rb file:
application.rb
module FirstEdc
class Application < Rails::Application
config.assets.initialize_on_precompile = false # I added this line
...
end
end
I then ran the precompile command, committed the changes, and managed to deploy successfully to heroku. However, now my bootstrap/css appears to have stopped functioning both on the heroku deployment, and my local deployment.
I learned that I was supposed to add another line to my deployment.rb file:
deployment.rb
FirstEdc::Application.configure do
...
# Allows for local precompilling --added by Ian
config.assets.prefix = '/dev-assets'
end
So I added this, recompiled and redeployed, but to no avail.
Finally, I ran a rake assets:clean in an attempt to at least get my local deployment back to normal, but it did not work.
Any advice would be greatly appreciated. I'm reading more into the asset pipeline now, but I feel like this could be a cache problem or something. I'll update as I figure out what's going on.
edit. Just to clarify, I've tried removing both additions, running a rake assets:clean and rake assets:clean:all, but neither fix my local deployment.
I don't use config.assets.prefix in any of my apps and they work just fine with Heroku, so not sure what that's doing.
Try removing that line, then running rake assets:clean. Now your local server should be using the files as you change them. When you want to push, run rake assets:precompile first, then push.
If you want to make changes locally after that, run rake assets:clean again to get rid of the precompiled files on your local machine.
If Heroku detects any files in public/assets it will not attempt to precompile your assets again. This is by design.
So, you need to make a decision to either always precompile your assets with rake assets:precompile, or remove any files in public/assets before pushing to Heroku.
(The recommended way is to allow Heroku to precompile them during push)
I am unable to run migrations in Heroku, which I believe is due to a module I created in my lib directory. After executing the command heroku run rake db:migrate I receive the below error:
uninitialized constant ApplicationController::PgTools
/app/app/controllers/application_controller.rb:4:in <class:ApplicationController>
Line 4 of the Application controller is include PgTools, which is there to gain access to methods within the PgTools module I created.
Despite the heroku migration failing, I am able to run rake db:migrate in my local dev environments without fail (please note that both environments utilize postgres databases).
I also have the following two lines in my application.rb file
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
I resolved the error by renaming Pg_Tools.rb to pgtools.rb and modifying all include PgTools statements to include Pgtools
Links that I used in the troubleshooting process are shown below
Rails 3 library not loading until require
http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
I'm attempting to deploy a web application on Amazon's EC2 servers, and I have the code up on the server. Everything looks like it's working, but when I go to the home page, I get a 500 error message and the production.log file gives me the following error:
ActionView::Template::Error (image.png isn't precompiled)
I've tried running rake assets:precompile,
I've changed the line in config/environments/production.rb to config.assets.compile = true
I've checked that the compiled image.png is in public/assets/manifest.yml
but I still get the same error.
I'm running Rails 3.2.6 and Ruby 1.8.7.
Thanks for your help!
Running rake assets:precompile RAILS_ENV=production should fix it.
If you don't provide any RAILS_ENV, Rails assumes it's development
I believe that's because each env in the asset pipeline behaves differently. Therefore, as a general rule, in production, always run rake tasks with RAILS_ENV='production' and you should stay safe.
I am using Openshift from Redhat and when deployed on the server it RAKEs to the production environment automatically. I too had the same problem but only on the production server.
Performing the change:
config/environments/production.rb to config.assets.compile = true
worked a treat. There is another parameter in this file vou could change:
config.assets.precompile += %w[ *.png *.jpeg *.jpg *.gif ]
When deployed on the server you could then do manually:
rake RAILS_ENV=production
or if you are using a server like Openshift that deploys automatically, configurations in the production.rb file will be taken into account.
In config/application.rb add a line like:
config.assets.precompile += ['image.png']
Although, if its in public/assets/images you shouldn't have to.
Resolved - needed to run rake assets:precompile RAILS_ENV='production instead of just rake assets:precompile ...
I've been running a Rails 3.1 app on Heroku Cedar Stack for a couple of months now. I'm using Rack::Deflater middleware to gzip my content and achieve this by
config.middleware.insert_before ActionDispatch::Static, Rack::Deflater
in my staging.rb file.
However, since last week, I get the following error when deploying to Heroku
Running: rake assets:precompile
rake aborted!
No such middleware to insert before: ActionDispatch::Static
However, running rake middleware still returns
use Rack::Cache
use Rack::Deflater
use ActionDispatch::Static
use Rack::Lock
And content served were still gzipped. However, assets were not compiled(minified) as pre-compilation failed. A manual rake precompile::asets also does not help.
So, I'm assuming ActionDispatch::Static is not available during pre-compilation of assets. So I tried to insert Rack::Deflater before Rack::Lock and now my assets are compiled without any error message but content served is not gzipped.
So, what do I need to do, to both gzip and compile my assets? What am I missing? Thanks.
Just a heads up Rack::Deflater is already used by Rails 3.1 so you don't need to manually do this.
BUT, to answer your problem here, I would assume that your production.rb has config.serve_static_assets = false set.
the ActionDispatch::Static middleware is only used when serve_static_assets is set to true. Heroku actually injects this config to override whatever you set anyway (see the Injecting rails3_serve_static_assets log message when you deploy), but I'm not sure at what stage in the deploy this happens.
So it's likely that you don't have static asset serving enabled when the assets:precompile runs (note this is just a guess, I'm not on Rails 3.1 yet so I could be wrong)
I would recommend against membLoper's suggestion of adding it manually in your rackup file:
it's not needed as explained above
your middleware that is relevant to your app should really be injected as you had originally tried in your application.rb
I still dont understand why Heroku does not recognize ActionDispatch::Static during pre-compilation of assets. However, Heroku folks did suggest a workaround to this issue.
The Rack::Deflater middleware needs to inserted in config.ru file rather than environment files. Something like,
require ::File.expand_path('../config/environment', __FILE__)
# Middleware to gzip content
use Rack::Deflater
run MyApplication
This way, it does not interfere with assets pre-compilation and still gzips the content being served.
Any resource on how config.ru works and where Rack::Deflater now resides is very welcome.