Sprockets does not require SQL files for custom rake task

85 Views Asked by At

Based on this article, which describes how to use Sprockets to write small SQL manifest files, I have my SQL views and functions automatically re-created on every rake db:migrate. This worked wonderfully until the last upgrade to Rails 5.1

Suddenly the manifest files get compiled, however every single *= require statement is ignored and I end up with an empty manifest file. I've tried several comment styles for the DirectiveProcessor, with and without file extensions, with and without relative paths. No matter what I provide, I end up with an empty file that gets executed via the DB.

my setup

db/functions/application.sql

/*
 * This is a manifest file that'll be compiled into application.sql, which will include all the files
 * from db/functions listed below.
 *
 *= require kill_all_connections.sql
 *= require invalidate_emails.sql
 *
 *= require days_until_birthday.sql
*/

lib/tasks/db_functions.rake

namespace :db do
  desc 'creates DB functions listed in db/functions.sql'
  task :functions => :environment do
    sprocket_env = Sprockets::Environment.new do |env|
      env.register_mime_type('text/sql', '.sql')
      env.register_processor('text/sql', Sprockets::DirectiveProcessor)
      env.append_path 'db/functions'
    end

    ActiveRecord::Base.connection.execute(sprocket_env['application.sql'].to_s)
  end
end

my result

looking at the console when I execute rails db:functions, I see the following:

(69.2ms)  /*
* This is a manifest file that'll be compiled into application.sql, which will include all the files
* from db/functions listed below.
*


*

*/

So the file gets executed but looks empty... Anyone has any ideas?

2

There are 2 best solutions below

2
On

Isn't Sprockets a bit overkill for the task of simply merging a bunch of files?

namespace :db do
  desc 'creates DB functions listed in db/functions.sql'
  task :functions => :environment do
    File.open(Rails.root.join('db','functions.sql'), 'w') do |dest|
      Dir[Rails.root.join('db', 'functions', '*.sql')].each do |f|
        File.copy_stream(f, dest)
      end
    end
    # ...
  end
end

If you need to have them in a specific order (to manage dependencies) just use an array instead of Dir[Rails.root.join('db', 'functions', '*.sql')].

0
On

Try adding the following line to the Sprockets environment configuration block:

env.register_bundle_processor 'text/sql', Sprockets::Bundle

Also, you can add the following line to support single-line SQL comments:

env.register_preprocessor 'text/sql', Sprockets::DirectiveProcessor.new(comments: ['--', ['/*', '*/']])