Rails供应商资产未提供..未找到路由错误

时间:2016-05-19 06:17:49

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 rubygems

我正在使用ruby 2.2和rails 4.2。

在我的应用程序中有许多CSS和JS文件,我只想在需要时从服务器加载。但是当我使用样式表链接标记从供应商的独立文件夹调用样式表时,我没有得到路由匹配错误< / p>

ActionController::RoutingError (No route matches [GET] "/vendor/theme/assets/stylesheets/application.css"):

application.css是我的单独清单文件,文件夹vendor/theme/assets/stylesheets/包含许多css文件。

我尝试将路由添加到“Rails.application.config.assets.paths”但仍无效。

我尝试使用公共文件夹用于相同的目的但仍无效。

是否可以在不预先编译这些资产的情况下为这些资产提供服务,因为只有一些页面需要这些资产。建议。

修改

我正在阅读本教程

http://railscasts.com/episodes/279-understanding-the-asset-pipeline?autoplay=true

资产文件夹中的资产工作得很好     http://localhost:3000/assets/application.css

但是http://localhost:3000/vendor/theme/assets/stylesheets/application.css正在给出找不到路线的错误

1 个答案:

答案 0 :(得分:1)

  1. 从您上面发布的代码中,您似乎正在尝试 在Rails应用程序中实现css主题。如果你,这就是我的方式 在我的应用程序中实现了主题功能。

    每当管理员对主题文件进行更改并更新它时,a 编译后的css文件生成/更新 带有主题名称的public / assets / themes /文件夹。那个文件是 应用程序根据当前应用的主题选择。 (我可以 如果这是您正在寻找的,请提供代码。)

  2. 要将资产仅提供给某些特定页面,您需要实现某种基于它加载资产的逻辑。例如。控制器特定资产:check here.

  3. 选项1的更新

    我有主题资源,我保存主题名称和两种主题颜色(你可以使用更多)。

    以下是我的观看表格的样子:

    <div class="field">
        <%= f.label :name %><br>
        <%= f.text_field :name %>
    </div>
    <div class="field">
       <%= f.label :color1 %><br>
       <%= f.text_field :color1 %>
    </div>
    <div class="field">
        <%= f.label :color2 %><br>
        <%= f.text_field :color2 %>
    </div>
    

    以下是我的ThemesController文件的样子:

    class ThemesController < ApplicationController
      after_action :compile_theme, only: [:create, :update]
      THEME_PATH = 'app/assets/'
      PATH = THEME_PATH + '/themes'
    
      def new
        @theme = Theme.new
      end
    
      def edit
        @theme = Theme.find(params[:id])
      end
    
      def create
        @theme = Theme.new(theme_params)
    
        if @theme.save
          # Create a scss theme file
          write_theme_file
    
          redirect_to @theme, notice: 'Theme was successfully created.'
        else
          render :new
        end
      end
    
      def update
        @theme = Theme.find(params[:id])
    
        if @theme.update(theme_params)
          # Create/Update a scss theme file, you can check for file exists 
          write_theme_file
          redirect_to @theme, notice: 'Theme was successfully updated.'
        else
          render :edit
        end
      end
    
      private
        def write_theme_file
          file = PATH + name + '.scss'
          body = "$color1: #{@theme.color1};\n$color2: #{@theme.color2};"
          File.write(file, body)
        end
    
        def compile_theme
          file = PATH + name + '.scss'
    
          theme_body = ''
          if File.exists?(file) && File.exists?(THEME_PATH + 'theme.scss')
            file = File.open(file)
            theme_body = file.read
            file.close
    
            file = File.open(THEME_PATH + 'theme.scss')
            theme_body = theme_body + file.read
            file.close
          else
            colors = ''
          end
    
          env = if Rails.application.assets.is_a?(Sprockets::Index)
            Rails.application.assets.instance_variable_get('@environment')
          else
            Rails.application.assets
          end
    
          Dir.mkdir(Rails.root + 'public/assets/themes') unless Dir.exists?(Rails.root + 'public/assets/themes')
          asset_file = File.join(Rails.root, 'public', asset_path(name))
          File.delete(asset_file) if File.exists?(asset_file)
    
          body = ::Sass::Engine.new(theme_body, {syntax: :scss, cache: false, read_cache: false, style: :compressed}).render
          File.write(File.join(Rails.root, 'public', asset_path(name)), body)
        end
    
        def asset_path(name)
          digest = Digest::MD5.hexdigest(name)
          "assets/themes/#{name}-#{digest}.css"
        end
    
        def name
          return @theme.name.downcase
        end
    
        def theme_params
          params.require(:theme).permit(:name, :color1, :color2)
        end
    end
    

    控制器方法说明:

    创建或更新新主题时,它会存储主题并在app / assets / themes中创建一个新的.scss文件,其中包含主题名称和定义的颜色值。

    css资产文件的编译和创建在创建/更新操作完成后发生。 compile_theme方法查找一个theme.scss(底部示例)文件(我已在app / assets / stylesheets /文件夹中创建了基本主题颜色变量)并用当前颜色值替换$ color1和$ color2变量主题文件。生成的css数据保存在theme_body变量中。

    body = ::Sass::Engine.new(theme_body, {syntax: :scss, cache: false, read_cache: false, style: :compressed}).render
    File.write(File.join(Rails.root, 'public', asset_path(name)), body)
    

    这两个最后一行将在public / assets / themes中创建一个新文件,其中包含theme_body css内容和带有theme_name和digest的文件名。

    现在您需要在每个页面中提取文件。为此,请在application_controller.rb文件中定义此

    before_filter :set_theme
    
    private
      def set_theme
        @theme = Theme.first # or change theme according to params
      end
    

    最后,您需要在布局文件中拾取主题文件。因此,请在layouts / application.html.erb文件中添加:

    <% if @theme.present? %>
       <% digest = Digest::MD5.hexdigest(@theme) %>
       <%= stylesheet_link_tag asset_url("assets/themes/#{@theme}-#{digest}.css") %>
    <% end %>
    

    仅供参考,以下是我的theme.scss文件的样子:

    body {
      background-color: $color1;
    }
    #header-wrapper, footer {
      background-color: $color2;
    }
    

    这就是全部。希望这可以帮助。如果您有任何问题,请告诉我。