获取Paperclip附件的绝对URL

26

如何获取Paperclip附件的绝对URI?目前的问题是生产环境部署在子URI上(通过Passenger:RackBaseURI),但<paperclip attachment>.url返回的是Rails应用程序相对URI(/system/images/...)。有没有一种方法来获取Paperclip附件的绝对URI?

我正在使用Paperclip v2.7和Rails 3.2.8。

7个回答

41

我认为它适用于Rails 4+? - Brendon Muir
4
asset_url 不能直接在控制器中使用,但是 URI.join 可以 :-) - Francis.TM
http://api.rubyonrails.org/classes/ActionView/Helpers/AssetUrlHelper.html#method-i-asset_url - ronan_mac

29

尝试

URI.join(request.url, @model.attachment_name.url)
或者
URI(request.url) + @model.attachment_name.url

如果您使用S3或绝对URL,则是安全的。

更新:这个答案比我的更好 ;) https://dev59.com/Z2cs5IYBdhLWcg3w0HSz#21027839


未定义局部变量或方法`request',位于#ModelName:0x000001083fd438中。 - kokemomuke
4
@kokemomuke,你不能在模型中执行此操作 - request 仅可在控制器和视图中使用。 - radex
我想知道如何在Grape Entities中实现这个...因为请求也不可用。有什么建议吗? - Fabiano Arruda

20
根据这个github issue,更好的做法是使用ActionController::Base.asset_host,这样会得到以下助手函数:
  def add_host_prefix(url)
    URI.join(ActionController::Base.asset_host, url)
  end

假设您在每个/config/environments/<environment>.rb文件中都有以下内容:

Appname::Application.configure do

  # ....

  config.action_controller.asset_host = 'http://localhost:3000' # Locally

  # ....

end

6
最广泛适用的方法是先在相关的config/environment文件中定义您的资产主机:
config.action_controller.asset_host = "http://assethost.com"
config.action_mailer.asset_host = "http://assethost.com"

然后在视图和邮件中:

asset_url(model.attachment.url(:style))

在控制台中:
helper.asset_url(model.attachment.url(:style))

在一个模型中:

ApplicationController.helpers.asset_url(model.attachment.url(:style))

5
你可以这样做:
<%= image_tag "#{request.protocol}#{request.host_with_port}#{@model.attachment_name.url(:attachment_style)}" %>

或者创建一个帮助方法来包装它。
def absolute_attachment_url(attachment_name, attachment_style = :original)
  "#{request.protocol}#{request.host_with_port}#{attachment_name.url(attachment_style)}"
end

然后像这样使用:

<%= image_tag absolute_attachment_url(attachment_name, :attachment_style)}" %>

例子:模型 = 个人 (@person),附件名称 = 头像,样式 = :thumb

<%= image_tag absolute_attachment_url(@person.avatar, :thumb)}" %>

2
注意。当设置了 config.action_controller.asset_host 时,这将无法正常工作,因为它会给你重复/损坏的协议+主机。 - glasz

4

虽然这并不能完全解决原帖作者的问题(它在视图中操作,而不是模型),但对于那些试图在视图中“获取Paperclip附件的绝对URL”的人可能会有所帮助:以同样的方式

image_tag(user.avatar.url(:large))

将图像本身放入您的视野中,
image_url(user.avatar.url(:large))

如果您想直接链接到资源(例如在link_to调用中),则只需返回您需要的URL。


Attachment#url方法具有误导性,因为它返回相对路径(如Routes_path方法),而不是完整的URL(如Routes_url方法)。谷歌搜索会出现几个“答案”,但它们都是hack。https://github.com/thoughtbot/paperclip/issues/584#issue-1548822 - Chris Bosco

2

您可以在application.rb中添加以下内容(或者在config/environments/*中针对特定环境):

config.paperclip_defaults = {
    url: "http://my.address.com/system/:class/:attachment/:id_partition/:style.:extension",
    path: ':rails_root/public/system/:class/:attachment/:id_partition/:style.:extension',
}

重新启动并重新导入您的图像。

附注:显然,您可以用环境变量替换http://my.address.com


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接