views:

659

answers:

3

I am hosting my assets on s3. In production, rails is looking for /javascripts/cache/all.js and /stylesheets/cache/all.css. I'm using a plugin to swoop the public directory over to s3 when I deploy with cap. The problem is that rails doesn't create these cache files until they are requested for the first time, so they aren't around during deployment when I transfer the public dir. Is there an easy way to force the creation of these files during deployment?

+4  A: 

The actual rails module that creates the cache files is ActionView::Helpers::AssetTagHelper which you may be able to re-use to create the cache files during deployment. The following worked okay for me:

require 'action_view'
class AssetCacheWriter

  include ActionView::Helpers::AssetTagHelper

  def write
    write_asset_file_contents(File.join(JAVASCRIPTS_DIR, "all.js"), compute_javascript_paths([:all], true))
    write_asset_file_contents(File.join(STYLESHEETS_DIR, "all.css"), compute_stylesheet_paths([:all], true))
'standard_all')
  end

end

Both those write_asset_file_contents calls I've lifted from the rails code. The _DIR constants are defined in the included module and the true parameters in the compute_xxx_paths calls indicate that all files should be included recursively.

I created a simple cap task that just wrote the files out:

namespace :sample
  task :assets do
    AssetCacheWriter.new.write
  end
end
Shadwell
+1  A: 

I use this in a rake task file. Saves you from creating an additional class and you keep it DRY because you're using the values from the stylesheet_link_tag / javascript_include_tag

desc "Clears javascripts/cache and stylesheets/cache"   task :clear => :environment do
  puts "Clearing javascripts/cache and stylesheets/cache"
  FileUtils.rm(Dir['public/javascripts/cache_[^.]*']) # use :cache => 'cache_all.js' in stylesheet_link_tag
  FileUtils.rm(Dir['public/stylesheets/cache_[^.]*']) # use :cache => 'cache_all.css' in javascript_include_tag
end

desc "Recreate the javascripts/stylesheets cache."
  task :generate => [:environment, :clear] do
  puts "Recreate the javascripts/stylesheets cache"
  ActionController::Base.perform_caching = true
  app = ActionController::Integration::Session.new
  app.get '/'
end
LeipeLeon
+1  A: 

If you're using Engine Yard Cloud, this is what I did:

added a file /lib/tasks/assetcache.rake

    require 'assetwriter'

    namespace :assetcache do

      desc "Clears javascripts/cache and stylesheets/cache"   
      task :clear => :environment do
        puts "Clearing javascripts/cache and stylesheets/cache"
        FileUtils.rm(Dir['public/javascripts/cache_[^.]*'])
# use :cache => 'cache_all.js' in stylesheet_link_tag
        FileUtils.rm(Dir['public/stylesheets/cache_[^.]*'])
# use :cache => 'cache_all.css' in javascript_include_tag
      end

      desc "Recreate the javascripts/stylesheets cache."
      task :generate => [:environment, :clear] do
        puts "Recreate the javascripts/stylesheets cache"
        AssetCacheWriter.new.write
      end

    end

then I added /lib/assetwriter.rb

require 'action_view' class AssetCacheWriter

include ActionView::Helpers::AssetTagHelper

def write write_asset_file_contents(File.join(JAVASCRIPTS_DIR, "cache/all.js"), compute_javascript_paths([:all], true)) write_asset_file_contents(File.join(STYLESHEETS_DIR, "cache/all.css"), compute_stylesheet_paths([:all], true)) end

end

then I added to /deploy/after_restart.rb

run "cd #{release_path} && bundle exec rake assetcache:generate"

Ryan Wilson