1

我有一个 Site 模型,它允许通过 Paperclip 将 background_image 上传到 S3。奇怪的是,每个站点在其模型中都有自己的 S3 凭据存储。我的问题是,通过 Paperclip 上传时如何引用网站自身的属性?

class Site < ActiveRecord::Base
  attr_accessible :background_image, 
                  :s3_access_key_id,
                  :s3_secret_access_key,
                  :s3_username

  has_attached_file :background_image,
                    storage: :s3,
                    s3_credentials: {
                      access_key_id: @s3_access_key_id.to_s,
                      secret_access_key: @s3_secret_access_key.to_s
                    },
                    bucket: "my-app",
                    s3_permissions: "public-read",
                    path: "/home/#{@s3_username}/background_images/:id/:filename"
end

不幸的是,通过这个设置,我得到了The AWS Access Key Id you provided does not exist in our records. 我认为它只是获取空白值,因为当我对数据库中的值进行硬编码时它工作正常。

4

1 回答 1

2

您的问题是在第一次阅读时在has_attached_file上调用,而不是在站点实例上。幸运的是,回形针在多个地方支持动态配置,您可以在其中检索实例在运行时。试试这个:Site site.rbSite

has_attached_file :background_image,
  s3_credentials: lambda { |attachment| attachment.instance.s3_keys },
  path: lambda { |attachment| "/home/#{attachment.instance.s3_username}/background_images/:id/filename" }


def s3_keys
  {
    access_key_id: self.s3_access_key_id.to_s,
    secret_access_key: self.s3_secret_access_key.to_s
  }
end

这些 lambda 表达式将在运行时进行评估,并将Paperclip::Attachment对象作为参数传入。您可以使用 检索Site实例Paperclip::Attachment#instance。因此,您可以调用实例上的方法来获取其特定的键。

您还可以使用更具体/更高级的技巧来s3_username进入路径。你可以教回形针更多的路径名称插值。就像你可以添加一个文件config/initializers/paperclip.rb

Paperclip.interpolates :s3_username do |attachment, style|
  attachment.instance.s3_username
end

然后你的Site模型可能看起来像

has_attached_file :background_image,
  s3_credentials: lambda { |attachment| attachment.instance.s3_keys },
  path: "/home/:s3_username/background_images/:id/:filename"


def s3_keys
  {
    access_key_id: self.s3_access_key_id.to_s,
    secret_access_key: self.s3_secret_access_key.to_s
  }
end
于 2013-10-04T21:39:57.460 回答