Rails asset pipeline tests pass production broken - ruby-on-rails-3

I had the following problem with the asset pipeline.
I have an HTML email with an image inside.
I have tests covering the case in which the email is sent successfully.
All tests pass.
When going to production, the feature requiring the email to be sent is broken, because the HTML layout is referencing a non existent image.
This obviously applies to all precompiled assets.
It seems to me that suddenly tests are no longer reliable. Is there any way to avoid this situation to happen again?

I found the perfect solution form my own case. If you set
config.assets.compile = false
config.assets.digest = true
in test environment, your tests will rely on precompiled assets.
Since it is annoying to precompile assets every time during quick development and testing phases, in my case it's enough to have this configuration on CI only.
You can setup an initializer called ci_config.rb with the following:
if ENV['CI']
class YourApp::Application
config.assets.compile = false
config.assets.digest = true
end
end
And configure you CI to run rake assets:precompile on start and rake assets:clean on end.

Compare the default configuration options in application.rb, production.rb and development.rb, and read Configuring Rails Applications in Ruby on Rails Guide to learn options.
Important options are, followings:
config.serve_static_assets: set this to false (production default), then, rails will not serve static contents.
config.assets.compile: whether compile assets using asset pipeline to compile if needed.
If you set above two options to false (that's the default for production), then you need to 1) precompile and place static contents at proper places, 2) configure web server (apache or nginx, may be) to serve static contents as needed.
So, for production, you need not only place the files, but also configure web server to serve them OR you can configure serve_static_assets to create assets on-the-fly. You may need to adjust test configuration but for test serve_static_assets is true unless you change it.

Related

export and maintain vue application

I have developed a vue application and did run npm run build
After that I uploaded the content in the dist file to my webpage but it returned a blank page.
Since I did this for testing I uploaded it to a folder in my public_html/mypage.com/vueapplication To get all the paths right I added a vue.config.js with this content:
// vue.config.js
module.exports = {
publicPath: '/vueapplication/'
}
The application now works but I wounder however:
how do I best publish/upload the application to my site? Just by simply dragging the content inte the right folder?
how can I best maintain my site? Do I need to build again and upload, overwriting my files when everytime I make an update on my site?
And what is the difference between build and deploy your application?
Drag and dropping your code should work. But as your app grows you may want to look into automating this. For instance if you use an S3 bucket you can use the aws cli to automate the upload.
Yes, you should overwrite your deploy folder(s). You need to also take care of deploying different binary files, that have the same name. An example is if you have a global css file (main.css for instance). The file will probably change content between deployments, but keep the same name. Browsers may cache the file so users that downloaded older versions of the file will not use the new one. There are different techniques to handle this, but if you use webpack, it uses cache busting techniques and you should be fine.
Build is the process of transforming source code into an artifact(s). Exactly what this means differs from language to language, platform to platform. In the vuejs world this usually means a couple of js files, a couple of css files and some assets.
Deploying means taking the output of a build and making it available to your users. Again this differs from project to project. In the vuejs world this usually means taking the artifacts from the build and uploading them to an http enabled web server.

Are Files in Public/Assets Required with Asset Pipeline?

I'm in the process of upgrading a 3.0 Rails App to 3.1.4 including the Asset Pipeline.
I'm on Heroku, so I'm I have this in my application.rb
config.assets.initialize_on_precompile = false
I noticed that when I run:
bundle exec rake assets:precompile
it creates files in a public/assets directory (even though my assets are in app/assets already).
For example, it creates files like application-72b2779565ba79101724d7356ce7d2ee, as well as replicating the images I have in app/assets.
My questions are:
(1) should be uploading these files to my production server?
(2) if I'm suppose to be uploading these, am I suppose to update each application-xxxxxxxx or only the latest one?
To your first question: Heroku will not allow you to modify the filesystem. So your assertion is correct- You will need to pre-compile the asset pipeline before you send it up to Heroku, so that it can be utilized in your production environment.
And the latter: You'll want to make sure you have the latest compilation. Any others wont be used. The "xxxxxxx" portion is to make sure that your users have the latest and greatest version of your assets. It's a way of versioning what the browser gets, and making sure they're not caching a bad copy of the JavaScript, when you want to set up their cache to hold on to the JS and CSS files as long as they can, instead of constantly getting it from your web server.
Take my Heroku comments with a slight grain of salt, as I have not deployed to Heroku before. I just know how their system works to some degree.

Preventing Heroku from using precompiled assets in development mode

Currently it seems Heroku is determined to pre-compile assets when I push my code up to my instances.
This is great for production servers, however for my "RAILS_ENV=development" server, this causes issues, as I now get pages with all the JavaScript files served up individually from my asset manifest, and then another file with the same code all grouped up as the pre-compiled asset.
This cause my jquery datatables libraries to break, throwing popup errors, which I don't get on my local environment (development or production) or in my production Heroku instance.
Is there anyway to disable pre-compilation of assets on Heroku for development mode instances ? Or is there any reason why these aren't already disabled on development Heroku servers already ?
If Heroku detect a public/assets/manifest.yml file then they will not attempt to precompile your assets and assume you are dealing with them yourself. More details at http://devcenter.heroku.com/articles/rails31_heroku_cedar
AFAIK, Heroku has to precompile assets to work around their readonly FS and the fact that the Rails asset pipeline wants to write files to the FS. The only thing I could suggest would be to work out why your assets are breaking when being compiled.
I worked around this by adding some voodoo to my Rakefile to disable the assets:precompile rake task.
first I add the user-env-compile labs component
heroku labs:enable user-env-compile
then add this to the beginning of my Rakefile
# found from http://blog.jayfields.com/2008/02/rake-task-overwriting.html
# used by conditional heroku asset compile magick
class Rake::Task
def overwrite(&block)
#actions.clear
enhance(&block)
end
end
Then I add this rake task in lib/tasks/disable_assets_on_heroku.rake
if ENV['RAILS_ENV'] == 'development'
namespace :assets do
task(:precompile).overwrite do
puts "Asset precompile skipped in #{ENV['RAILS_ENV']}"
end
end
end

Serve assets directly (No asset pipeline) in development?

Rails 3.1 loads pages terribly slow in development. It's processing them through the pipeline, one at a time, and takes way too long.
Is it possible to precompile my assets (which I'm not testing right now, so static files are fine) and have Rails not be responsible for serving them? Would that make things faster?
Update: Got a solution.
Richard Hulse has the correct answer to this question. rake assets:precompile will prebuild assets so they are served directly, without the asset pipeline.
But Frexuz's answer solves the problem of slow loading I've been having. Loading the Rails-dev-tweaks gem makes page loading in development markedly faster.
I had the same problem! It could take from 2-4 seconds extra to load a page because of the assets.
Take a look here (a gem): Rails 3.1 is very slow in development-mode because of assets, what to do?
This made serving assets almost instant (server console says 1ms per asset), using the asset pipeline normally.
Yes.
You can run the precompile task (in 3.1.1) and it will just work - the precompile task will give you assets without fingerprints as well as with, which is what you need in development mode. (Fingerprints are not added in dev mode).
Beware that you don't commit these to source control though.
What is more of a concern is the slowness. I have 4 stylesheets and 15 javascript files in my manifests, and it is only a bit slow on the first request.
What do you see in your logs when the assets are accessed? You should be able to see them being compiled on the first hit and each subsequent request should be a 304 not modified.
Also, do your config settings for dev match those in the asset pipeline guide? If you were compressing in dev mode with lots of files, this could be a source of slowness.

cache manifest with asset pipeline

What would be the best way to have a html5 cache manifest with the rails asset pipeline? I'm thinking of adding an erb file to app/assets that has the paths of all the assets contained in it. This would work but has a couple problems right off the bat:
How could I increment the version number?
How can I make sure the http content type is set correctly?
Here's how we're doing it on an app right now:
To handle the generation of the cache manifest file, we are using Rack::Offline
We then configure this to point to, for instance, "/assets/application.css"
In the layouts/views, we are NOT using the stylesheet_link_tag, javascript_include_tag or image_tag helpers for cache-able assets so that we don't get a link to the assets with the hash in it, eg "/assets/application-2345234...2344.css"
This works because when the assets are precompiled, rake assets:precompile:nondigest creates versions of the files without the hash in the name, and then Rack::Offline checks these to generate a new manifest (or not).
Sprockets provides you with one by default.
in one of your environment configs (/config/environments/development.rb)
config.assets.compress = false
config.assets.debug = false
and in your html file:
<html manifest="manifest.yml">
running
rake:precompile
will give you a manifest file to public/assets/manifest.yml