module Engineer::Database::ResolveScenicViewsAnywhere
The scenic gem supports loading SQL view definition files from a db/views folder but only supports one folder (it looks in app.config.paths and takes the last one) which works fine if you are using a rake task to copy all your views from various engines into the host app. But this a bit issues prone and it is much nicer to add each engine's db/views folder to app.config.paths (we do this in the Engineer::Database::Initializers
class provided the engine includes the appropriate file) and then here we override the Scenic Definition#to_sql method and when a view definition file is requested, search all db/views paths - which may search in several engines and host app itself - and hopefully find the file we are looking for. In theory that file should be in the same engine/app that its corresponding migration is in… though we can't verify that and its unlikely We raise an error if we find two matching files i.e. a view definition file of the same name in two gems.
Public Instance Methods
# File lib/engineer/database/scenic.rb, line 37 def all_full_paths app = Rails.application return super unless defined?(app) && app.present? app.config.paths["db/views"].map { |path| File.join(path, filename) } end
# File lib/engineer/database/scenic.rb, line 28 def find_view_definition_among_all_possible_paths found_files = all_full_paths.select{ |path| File.exist?(path) } if found_files.length > 1 raise "More than one view definition matches the name #{filename}\n #{found_files}" end found_files.first end
# File lib/engineer/database/scenic.rb, line 18 def to_sql view_definition_file = find_view_definition_among_all_possible_paths File.read(view_definition_file).tap do |content| if content.empty? raise "Define view query in #{path} before migrating." end end end