如何从 Rails 3.1 的控制器引用已编译的资源?
我在控制器中使用 PDFkit 构建一系列 PDF,将它们压缩,然后将它们发送给用户。
为了控制输出样式,我告诉 PDFKit 在内容生成期间使用哪些样式表。我需要传递 CSS 文件的文件引用。由于 Rails 现在正在编译并重命名我的样式表,因此我不确定如何在控制器内引用已编译的 CSS 资源。
这是我以前所做的:
InvoicesController < ApplicationController
def download
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << "#{Sass::Plugin.options[:css_location]}/application.css"
kit.to_file("#{file_date_string}.pdf")
# snip
end
end
Sass::Plugin.options[:css_location] 现在返回错误的位置,更不用说 application.css 不再是文件的有效名称了。我应该提到,我有一个 app/assets/application.css 文件作为我的 SCSS 文件的清单,并且它通过 stylesheet_link_tag() 方法在我的视图中正常工作。
基本上我正在寻找的是一个相当于 asset_path() 的控制器,以便执行以下操作:
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << asset_path('application.css')
kit.to_file("#{file_date_string}.pdf")
任何人都可以帮忙吗?
I'm using the PDFkit in my controller to build out a series of PDFs, zip them up, and then send them to the user.
In order to control the output styles, I tell PDFKit which stylesheets to use during content generation. I need to pass along the file reference of the CSS file. Since Rails is now compiling and renaming my stylesheets, I'm not sure how to reference the compiled CSS asset inside my controller.
Here's what I used to do:
InvoicesController < ApplicationController
def download
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << "#{Sass::Plugin.options[:css_location]}/application.css"
kit.to_file("#{file_date_string}.pdf")
# snip
end
end
Sass::Plugin.options[:css_location] now returns the incorrect location, not to mention the fact that application.css is no longer the valid name of the file. I should mention that I have an app/assets/application.css file that serves as a manifest for my SCSS files, and it is working correctly in my views via the stylesheet_link_tag() method.
Basically what I'm looking for is a controller equivalent of asset_path() in order to do something like this:
kit = PDFKit.new(render_to_string(:show, :layout => false))
kit.stylesheets << asset_path('application.css')
kit.to_file("#{file_date_string}.pdf")
Can anyone help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Rails.application.assets 的文档很少,但它提供了对 Rails 挂钩到 Sprockets 的访问,作为一个 Sprockets::Environment 对象。 Rails 使用 Sprockets 来运行整个资产管道,您应该在此处进行如下操作:
https:// /github.com/sstephenson/sprockets 说道:
以编程方式访问资产
您可以使用
find_asset
方法(别名为[]
) 从 Sprockets 环境中检索资产。向其传递一个逻辑路径,您将获得一个Sprockets::BundledAsset
实例:在生成的资源上调用
to_s
来访问其内容,length
获取其长度(以字节为单位),mtime
查询其上次修改时间,pathname
获取其在文件系统上的完整路径。Rails.application.assets
is poorly documented but it provides access to Rails' hook into Sprockets, as aSprockets::Environment
object. Rails uses Sprockets to basically run the whole asset pipeline, and this is where you should hook in for things like this:https://github.com/sstephenson/sprockets says of it:
Accessing Assets Programmatically
You can use the
find_asset
method (aliased as[]
) to retrieve an asset from a Sprockets environment. Pass it a logical path and you'll get aSprockets::BundledAsset
instance back:Call
to_s
on the resulting asset to access its contents,length
to get its length in bytes,mtime
to query its last-modified time, andpathname
to get its full path on the filesystem.view_context.asset_path 'application.css'
应该可以解决问题。view_context.asset_path 'application.css'
should do the trick.Rails.application.assets['application.css'].pathname 始终返回原始资源的原始路径,而不是预编译文件,因此最上面的答案对我不起作用。
但是,在捆绑资源上调用
to_s
而不是pathname
似乎确实可以正确返回预编译资源的主体,因此您可以只使用内联样式而不是使用kit.stylesheets <<
:Rails.application.assets['application.css'].pathname
always returns the original path of the raw asset, not the precompiled file, so the top answer did not work for me.However, calling
to_s
on the bundled asset instead ofpathname
does seem to correctly return the body of the precompiled asset, so you can just use an inline style instead of usingkit.stylesheets <<
:<style>
<%= Rails.application.assets["application.css"].to_s %>
</style>
一种解决方案是将 CSS 内联到您的视图中。
在 HAML 中,这可能如下所示:
或者在 ERB 中:
One solution is to pull the CSS inline in your view.
In HAML, this could look like:
Or in ERB:
获取编译名称的最佳方法是从编译时生成的清单中获取。
您可以创建一个在开发中提供原始名称的控制器方法,然后在生产中访问清单以映射正确的名称。
默认情况下清单的位置是:
File.join(Rails.public_path, config.assets.prefix, 'manifest.yml')
但看起来您可以在 config.assets.digests 中以哈希形式访问它
config.assets.digests[css_file_name_as_string]
The best way to get the compiled name is from the manifest that is generate when you compile.
You can make a controller method that serves the raw name in development, and then accesses the manifest in production to map the correct name.
The location of the manifest by default is:
File.join(Rails.public_path, config.assets.prefix, 'manifest.yml')
But it looks like you can access this as a hash at config.assets.digests
config.assets.digests[css_file_name_as_string]
我认为 stylesheet_path("application") 就是您要找的
I think stylesheet_path("application") is what you're looking for