What exactly was initialize_on_precompile used for? - ruby-on-rails

I'm having trouble understanding what initialize_on_precompile was used for. What exactly did it mean for it to be false (especially as it relates to Heroku)? What did it mean for it to be true?
Apologies if this question is too broad/vague, but I can't seem to find the answer anywhere.

This option was available till Rails 3.x as when you run rake assets:precompile it initializes the application and tries to connect to the database. So setting this option to false prevents it. So if you have any issues in connection to the database rake assets:precompile won't work and fail this option ensures that it will work.
From Rails Git Repo:
The initialize_on_precompile change tells the precompile task to run without invoking Rails. This is because the precompile task runs in production mode by default, and will attempt to connect to your specified production database. Please note that you cannot have code in pipeline files that relies on Rails resources (such as the database) when compiling locally with this option.
In Rails 4.x this option has been removed and is no longer required. Rails 4 now always loads initializers and the database configuration before precompiling assets
Source of Commit: https://github.com/rails/rails/commit/2d5a6de

Related

Paymill + Heroku + Rails 4 No Token Found Error

I've integrated Paymill successfully in my ROR4 App using their Paymill Bridge. All works fine in development mode, but as soon as I deploy it to production, it returns me the "NO TOKEN FOUND".
This used to happen in development mode because it was not loading the transactions.js properly due to turbolinks, I have fixed it since.
But cannot make it work in production
Thanks!
All the Best
since the introduction of the assets pipeline, rails uses gem uglier to compress (remove whitespaces, shorten function and variable names, etc.) the custom JavaScript. This is done by the command rake assets:precompile, which is executed on each deploy to heroku.
I think you should take a look at uglifier and try to overwrite the default settings. My first guess is that you have to set :unused to false. Because the PAYMILL_PUBLIC_KEY variable is used by PAYMILL bridge and not by your scripts.
You can test this on your local machine by calling: rake assets:precompile and check the generated JavaScript.

Why is my heroku app trying to connect to a database during asset compilation?

I recently put a Rails app I've been working on up on Heroku. When I push to my Heroku git repository it runs the asset compilation as part of generating the slug. It was failing here with the following error:
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port xxxx?
The problem is that the rake task, rake assets:precompile, is trying to connect to the database and my app does not have access to config vars during slug compilation. I found this information in Heroku's troubleshooting documentation and added the prescribed fix in my application.rb file:
config.assets.initialize_on_precompile = false
Now my assets get compiled correctly and the images in my gem's vendor/assets are usable.
Questions
Why is the asset compilation rake task trying to connect to the database in the first place?
Heroku also allows the assets to be compiled either locally and added to the git repo or during runtime. I believe these other two options won't run into the same problem as it only occurs during slug compilation. Is there any advantage in either of these?
The task will likely have a dependency on :environment, which will load your whole application, including the startup code, where the database connection is established.
Asset precompilation serves the purpose to improve request time - rails doesn't have to compile the assets at every request. If you compile the assets locally, you are using your own machine, which most likely will be faster than the heroku env. You can easily use a hook to do the compilation automatically.
config.initialize_on_precompile tells rake whether or not to load your full rails application during the asset compilation task, and that includes connecting to the database. As for compiling locally, no, there isn't much benefit to doing that.

Updating assets without restarting rails server

So the question basically boild down to this:
How do you efficiently handle changing assets in a production rails environment without the need to restart the server?
The problem we're experiencing is, we have to restart the Thin server that runs the app in order for the updated javascript files to be served.
Some background:
Right now we're generating data from a couple of long running tasks into javascript files once an hour so we can use it in our Rails app.
To be clear, we update/overwrite existing files, not adding new ones.
After generation we run these commands in order to re-precompile all the assets.
bundle exec rake assets:precompile
bundle exec rake rails_group=assets assets:clean RAILS_ENV=production
Still after clearing the browser cache and reloading the page we're being served the old assets.
Have you guys made any similar experiences; what did you do to work around it?
PS. Happy holidays to you all!
So, what we ended up doing is basically letting rails also serve static assets by setting
config.serve_static_assets = true
in config/environments/production.rb
and just putting the frequently changing javascript data files into a directory structure under public/.
This works grate since it also separates assets and data into different locations.
According to the Rails guide:
6 How Caching Works Sprockets uses the default Rails cache store to
cache assets in development and production.
Rails is going to cache your assets unless you tell it to not cache them. The whole point of the asset pipeline is to serve assets as quickly as possible by encouraging browsers and servers and the rails servers themselves to cache the assets.
If your use case involves redoing assets very often, maybe the asset pipeline isn't for you.

Conditionally disable asset precompile in Capistrano

I've seen various convoluted and generally ineffective solutions to performing lazy asset precompile in Rails. As a backend developer I don't particularly want to recompile assets I never touch every time the program deploys, but because assets are loaded in Capfile via load 'deploy/assets', and not by defining a task in deploy.rb, I can't think of a way to conditionally disable it.
The behaviour I'm after is to use cap deploy for regular with-precompile deployment, and to use cap deploy:no_assets to skip asset deployment.
Both turbo-sporocket-rails and the that auto-skip scripts have some pitfalls (I will mention later). So I use the following hack, so I can pass a parameter to skip asset pre-compile at my will:
callback = callbacks[:after].find{|c| c.source == "deploy:assets:precompile" }
callbacks[:after].delete(callback)
after 'deploy:update_code', 'deploy:assets:precompile' unless fetch(:skip_assets, false)
This script will change the built-in asset-precompile hook, so it will be hooked based on the skip_assets parameter. I can call cap deploy -S skip_assets=true to skip asset precompile as a whole.
For me, turbo-sporocket-rails still takes minutes to do the checking when nothing has changed. This can be crucial when I need to push a fix to the server asap. Therefore I need my force-skipping method.
rails4 addresses this issue with it's new version of sprockets, by only precompiling assets that have changed. In the mean time, for your rails3 apps I recommend the turbo-sprockets-rails3 gem.
This gem started out as a set of patches for sprockets-rails by Nathan Broadbent, which were not merged into master because the problem was already addressed in rails4. From the README:
Speeds up your Rails 3 rake assets:precompile by only recompiling changed assets, based on a hash of their source files
Only compiles once to generate both fingerprinted and non-fingerprinted assets
And:
turbo-sprockets-rails3 should work out of the box with the latest version of Capistrano.
I can confirm that it works well for me on rails-3.2.x apps deploying with Capistrano.
As a side note for GitHubbers, the original pull request is an excellent example of how to submit code to an open source project, even if it wasn't merged.
This gist looks very promising https://gist.github.com/3072362
It checks your git log from the last deploy to now to see if there are any changes in %w(app/assets lib/assets vendor/assets Gemfile.lock config/routes.rb) and if so, only precompiles then.

Rails 3.1.1 asset pipeline Heroku caching gotcha

The problem in a nutshell is that in development mode we'd make changes to CSS or JS files but would always get cached/old versions of these files. Nothing I did had any effect. I checked configuration dozens of times and tried every combination of config values but always kept getting the same results: stale/cached files. I had to actually run in production mode and restart the server after every change to test.
I spent days tearing my hair out over this issue, looked at dozens of stackoverflow questions on the asset pipeline but never found one that addressed it so I thought I'd post it here for posterity.
We use Heroku and precompile our assets because Heroku fails to precompile for us (we also use devise which apparently is the cause of the heroku precompilation failure). So in order to push our precompiled assets up to Heroku we have to check them in to git.
Here's the problem.
When we upgraded to Rails 3.1.1 asset precompilation produced files both with and without the MD5 hash in the name. I didn't think much of this and went ahead and checked all these files in so I could push to heroku. Sometime later I noticed the problem with cached results in development mode. The precompiled and checked in assets without the MD5 hashes were being served from /public/assets as static files which prevented us from seeing any changes we were making in /app/assets.
After finally realizing this I ran git rm /public/assets and everything works again. So the takeaway is: Be careful checking assets into git!
To turn this into a question: how do others do this? Am I missing something obvious? What I'd really like is for Heroku to precompile my assets for me but it is failing with a db connection error that I gather is because of devise. I had hoped Rails 3.1.1 fixed this but it didn't.
Have you checked out this devise issue on github? Specifically Jose Valim says
Rails 3.1.1 final has a method called
config.assets.initialize_on_precompile. If you set it to false, you
should be good but it won't allow you to access model information on
your assets (which you probably shouldn't anyway).
Maybe this will allow the precompile to happen on Heroku for you.
The reason the asset precompilation does not work could well be, that the Heroku ENV vars are not present on slug compilation (deploy) as stated here:
http://devcenter.heroku.com/articles/rails31_heroku_cedar
There is an (experimental) way to enable the ENV vars during deploy for exactly this reason, find information here:
http://devcenter.heroku.com/articles/labs-user-env-compile
Hope this helps.
Check this guide from Heroku. It outlines the 3 ways to deploy Rails 3.1 apps. Two of these do not required local precompilation.

Resources