我有一个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
。我假设它只是获取空白值,因为当我对数据库中的值进行硬编码时它可以正常工作。
答案 0 :(得分:1)
这里的问题是has_attached_file
是Site
类在首次读取site.rb
时被调用,而不是在网站实例上。幸运的是,paperclip支持在几个地方进行动态配置,您可以在运行时检索Site
实例。试试这个:
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