Rails 3.1 Asset Pipeline не прекомпилирует файлы из другого каталога

В настоящее время у меня есть приложение Rails 3.1, в котором размещено несколько сайтов для нескольких разных клиентов. Каждый сайт представлен моделью, которая знает имя домена и путь к месту хранения активов, а также некоторую другую информацию.

Я использовал app/sites/domain-name в качестве места для хранения активов, представлений и локалей, специфичных для данного сайта, и запустил пользовательское промежуточное ПО и действия контроллера для изменения пути загрузки для Sprockets, настройки путей представлений и т. д.

middleware (загружен с помощью config.middleware.use "Configurator" в application.rb):

class Configurator
  def initialize(app)
    @app = app
  end

  def call(env)
    @env = env
    clear_existing_paths
    prepend_local_assets
    @app.call(env)
  end

  def current_site
    # find site using @env
  end

  def current_site_path
    Rails.root.join('app', 'sites', current_site.path)
  end

  def clear_existing_paths
    paths = Rails.application.assets.paths
    Rails.application.assets.clear_paths
    paths.each do |path|
      next if path.include?("app/sites/")
      Rails.application.assets.append_path path
    end
  end

  def prepend_local_assets
    path = current_site_path.join('assets')
    return unless Dir.exists?(path)

    ['images', 'javascripts', 'misc', 'stylesheets'].each do |subdir|
      asset_dir = path.join(subdir).to_s
      next unless Dir.exists?(asset_dir)
      next if     Rails.application.assets.paths.include? asset_dir

      Rails.application.assets.prepend_path asset_dir
    end
  end
end

Биты активов из application.rb:

module MyApp
  class Application < Rails::Application
    ...
    config.middleware.use "Configurator"

    config.assets.enabled = true 
    config.assets.version = '1.0'
  end
end

И environments/production. rb:

MyApp::Application.configure do
  config.serve_static_assets = false
  config.assets.compress = true
  config.assets.compile = true
  config.assets.digest = true
  # Defaults to Rails.root.join("public/assets")
  # config.assets.manifest = YOUR_PATH
end

Проблема в том, что хотя эта настройка работает, она не позволяет мне предварительно скомпилировать активы, которые не являются общими для всего приложения, заставляя генерировать их снова и снова, судя по всему.

Могу ли я как-то указать прекомпилятору найти активы, расположенные здесь, и создать их версию? Каждый сайт имеет site.css.scss и site.js.coffee файл, которые могут потребовать других активов внутри site-dir. Было бы неплохо, если бы я мог получить его предварительно скомпилированным в public/assets/domain-name/site. (js|css), чтобы я мог легко создать отдельный поддомен для активов, когда мне понадобится дальнейшая оптимизация

Окончательное решение (2012-02-22)

После реализации того, что предложил Брайан, я получил

Главная таблица стилей/javascript хранится в app/sites//assets//site. css|js, где sitename - домен для этого сайта, а shortname - основная часть домена, без поддомена или com|org|net|ccTLD.

Изменил все представления и таблицы стилей, чтобы добавить shortname в пути к активам.

В config/application.rb:

{ "sitename" => "shortname", ... }.each_pair do |domain, short|
  %w{stylesheets javascripts}.each do |dir|
    config.assets.paths << Rails.root.join("app/sites/#{domain}/assets/#{dir}").to_s
  end # Had to specify each dir to make it work
  config.assets.precompile += ["#{short}/site.css", "#{short}/site.js"]
end

При выполнении rake assets:precompile создается public/assets/shortname, заполненный всеми активами для этого сайта, а public/assets содержит все общие активы. Работает отлично для моих нужд.

И поскольку все оказалось в public/assets, я смог отказаться от Configurator-middleware, поскольку конфигурация по умолчанию смогла найти все активы

9
задан PerfectlyNormal 22 February 2012 в 19:29
поделиться