显示存储在非公用文件夹中的回形针附件

时间:2014-08-31 13:41:23

标签: ruby-on-rails paperclip attachment

我的难题是如何在一个html页面中嵌入一个图像,该图像的来源不适用于整个互联网。

让我们说,在Rails / Paperclip设置中,我有以下型号:

class Figure < ActiveRecord::Base
  has_attached_file :image
  ...
end

class User < ActiveRecord::Base
   ... (authentication code here)
   has_many :figures
end

在控制器中:

class FiguresController < ActionController::Base
  def show
    # users must be authenticated, and they can only access their own figures
    @figure = current_user.figures.find(params[:id])
  end
end

在视图中:

<%= image_tag(@figure.image.url) %>

当然,问题在于,使用默认的Paperclip设置,图像存储在公共目录中,任何有链接的人都可以访问存储的图像,绕过身份验证/授权。

现在,如果我们告诉Paperclip将附件存储在私人位置:

class Figure < ActiveRecord::Base
  has_attached_file :image, path: ":rails_root/private/:class/:attachment/:id_partition/:style/:filename",
                             url: ":rails_root/private/:class/:attachment/:id_partition/:style/:filename"
  ...
end

然后很容易控制图像的送达对象:

class FiguresController < ActionController::Base
  def show
    @figure = current_user.figures.find(params[:id])
    send_file @figure.image.path, type: 'image/jpeg', disposition: 'inline'
  end
end

此操作的效果是在其自己的浏览器窗口/选项卡中显示图像。

另一方面,image_tag(@figure.image.url)可以理解地产生路由错误,因为无法访问源代码!

因此,有没有办法在常规HTML页面中通过image_tag显示图像,同时仍然限制对它的访问?

1 个答案:

答案 0 :(得分:0)

您需要更改传递给:url的{​​{1}}选项,使其与数字控制器的路由匹配。

例如,如果图中的正确网址为has_attached_file且为123,那么您传递给/figures/123的网址应为

has_attached_file

甚至

'/figures/:id'

由于'/:class/:id' 段将插入到名称的复数小写下划线形式。如果需要,您还可以附加扩展名或文件名(但是您必须稍微更改控制器代码以提取ID)