Rails应用程序正在请求生产中不存在的预编译资产

时间:2013-12-30 09:10:03

标签: ruby-on-rails asset-pipeline

我通过运行bundle exec rake assets:precompile在本地预编译资产并将它们提交到我的git repo。在使用Capistrano将其部署到生产服务器之后,我才意识到某些资产缺失,但其他一些资产已经找到并且没问题。

我打开浏览器,查看页面来源。似乎我的应用程序正在请求服务器中不存在的资产,如下所示:

http://mywebsite.com/assets/users-97ff9cd1fc91c7ec829ef21dac3540b1.css 

上面的网址导致Firebug显示 NetworkError:404 Not Found

然而,在我的'public / assets'路径(生成预编译资产的位置)中,名为users-97ff9cd1fc91c7ec829ef21dac3540b1.css的文件 不存在。

在我的 manifest.yml 中, users.css 文件实际上指向一个名为的文件 users-807c131fa112764e83fdbcd416b3f3fa.css 它存在于服务器中。所以请求应该被指定给这个文件。

manifest.yml

...    
users.css: users-807c131fa112764e83fdbcd416b3f3fa.css
...

正如您可能猜到的那样,URL应该发送到现有文件:

http://mywebsite.com/assets/users-807c131fa112764e83fdbcd416b3f3fa.css

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

问题是asset fingerprinting,是Rails的标准功能


资产指纹识别

  

指纹识别是一种使文件名依赖的技术   关于文件的内容。当文件内容改变时,   文件名也被更改。对于静态或不经常的内容   改变了,这提供了一个简单的方法来判断是否有两个版本   文件是相同的,甚至跨越不同的服务器或部署日期

这基本上意味着管道中的每个资产都会附加一个哈希键,以确保唯一性

为了适应这种情况,您需要使用SASS

等技术动态引用管道中的资产

动态参考

好消息是预编译后Rails会自动访问.css.js,但是,如果你引用特定的资产文件(如图像),你会有动态引用它们

这就是我的意思:

#app/assets/stylesheets/users.css
.hello {
    background: url("google-home.png"); /* - doesn't work with precompiling, as references static object */
}

#app/assets/stylesheets/users.css.scss
.hello {
    background: image_url("google-home.png"); /* - dynamic reference using one of the SASS Rails Helpers */
}

希望这有帮助吗?

答案 1 :(得分:0)

使用capistrano部署应用程序时(以及生产服务器上的capistrano预编译资产)共享/资产目录符号链接到公共/资产,所有已发布的版本都可以访问应用程序的资产。

在这种情况下,您的存储库包含一个public / assets目录。 您是否在生产服务器上有共享/资产目录? 你能看到旧版本上的 users-97ff9cd1fc91c7ec829ef21dac3540b1.css 文件吗?

我认为您有充分的理由预先编译您的资产,因此您可以尝试其他解决方案:

或者

  • 在预编译之前清理资产:

    RAILS_ENV=production bundle exec rake assets:clean assets:precompile

希望得到这个帮助。