如何将Rails引擎的/ / public文件夹复制到生产中的Rails应用程序?

时间:2016-07-04 10:32:40

标签: ruby-on-rails asset-pipeline bundler

我知道一个简单的解决方案就是手动将Rails Engine' s / public文件夹中的所有文件复制到Rails应用程序的/ public文件夹。但是,这意味着每次安装都需要手动复制。

此外,因为我的引擎使用的Javascript文件具有硬编码的图像路径,所以我不能简单地将所有静态文件放在app / assets或vendor / assets下,因为Rails会将它们复制到public / assets。我无法更改Sprockets输出文件的路径,因为我有其他宝石,期望他们的资产位于默认的公共/资产文件夹中。

我尝试过像

这样的事情
    class Engine < ::Rails::Engine
        if Rails.application.config.serve_static_assets
            initializer "static assets" do |app|
              app.middleware.insert_before(::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public")
            end
        end
    end

但这仅适用于开发。

1 个答案:

答案 0 :(得分:3)

就个人而言,我认为最好的解决方案是更新您的javascript文件以遵循Rails的惯例,将javascript中的硬编码图像替换为资产路径帮助程序 - http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets,然后将所有内容放入应用程序/资产。

话虽如此,我可以想到你可能不想这样做的情况,这可能就是这种情况。

从你的帖子中,我猜你正在为生产预编译资产(即 - 运行rake资产:预编译)。在这种情况下,您可以挂钩资产:预编译rake任务并复制文件。它会在您的引擎的lib / tasks / my_engine_tasks.rake中看起来像这样:

Rake::Task["assets:precompile"].enhance do
  Rake::Task["my_engine:copy_assets"].invoke
end

namespace :my_engine do
  task :copy_assets => :"assets:environment"  do
    assets = ["file1", "file2"]
    assets.each do |asset|
      source_file = File.join(MyEngine::Engine.root, 'public', asset)
      dest_file = File.join(Rails.root, 'public', asset)
      FileUtils.copy_file source_file, dest_file, true
    end
  end
end

以上是一个简单的复制操作,但您也可以在这些文件上手动运行sprockets。看一下资产的代码:预编译任务(sprockets-rails gem中的lib / sprockets / rails / task.rb)和Sprockets Manifest类(sprockets gem中的lib / sprockets / manifest.rb)。