我想存储收到的电子邮件附件以及回形针的使用情况。从电子邮件我得到part.body,我不知道如何把它放到回形针模型。现在我创建临时文件并将port.body写入其中,将此文件存储到paperclip,然后删除文件。以下是我使用临时文件的方法:
l_file = File.open(l_path, "w+b", 0644)
l_file.write(part.body)
oAsset = Asset.new(
:email_id => email.id,
:asset => l_file,
:header => h,
:original_file_name => o,
:hash => h)
oAsset.save
l_file.close
File.delete(l_path)
:asset是我的'has_attached_file'字段。有没有办法省略文件创建并执行以下操作::asset => part.body in Asset.new?
答案 0 :(得分:21)
假设您使用mail gem阅读电子邮件,我会这样做。你需要整个电子邮件'part',而不仅仅是part.body
file = StringIO.new(part.body) #mimic a real upload file
file.class.class_eval { attr_accessor :original_filename, :content_type } #add attr's that paperclip needs
file.original_filename = part.filename #assign filename in way that paperclip likes
file.content_type = part.mime_type # you could set this manually aswell if needed e.g 'application/pdf'
现在只需使用文件对象保存到Paperclip关联。
a = Asset.new
a.asset = file
a.save!
希望这有帮助。
答案 1 :(得分:9)
Barlow的答案很好,但它实际上是对StringIO类进行猴子修补。在我的情况下,我正在使用Mechanize :: Download#body_io,我不想污染这个类导致在应用程序中突然出现的意外错误。所以我在实例元类上定义方法如下:
original_filename = "whatever.pdf" # Set local variables for the closure below
content_type = "application/pdf"
file = StringIO.new(part.body)
metaclass = class << file; self; end
metaclass.class_eval do
define_method(:original_filename) { original_filename }
define_method(:content_type) { content_type }
end
答案 2 :(得分:6)
我喜欢gtd的答案,但它可以更简单。
file = StringIO.new(part.body)
class << file
define_method(:original_filename) { "whatever.pdf" }
define_method(:content_type) { "application/pdf" }
end
并不需要提取&#34;元类&#34;进入局部变量,只需将一些类附加到对象。
答案 3 :(得分:2)
从ruby 1.9开始,您可以使用StringIO和define_singleton_method:
def attachment_from_string(string, original_filename, content_type)
StringIO.new(string).tap do |file|
file.define_singleton_method(:original_filename) { original_filename }
file.define_singleton_method(:content_type) { content_type }
end
end
答案 4 :(得分:0)
作为对David-Barlow的回答的评论本来会更好,但是我还没有足够的声望点...
但是,正如其他人提到的那样,我不喜欢猴子打补丁。相反,我只是创建了一个从StringIO继承的新类,如下所示:
class TempFile < StringIO
attr_accessor :original_filename, :content_type
end
答案 5 :(得分:0)
为了后代,这是最好的答案。将顶部放在 vendor/paperclip/data_uri_adapter.rb 中,将底部放在 config/initializers/paperclip.rb 中。
这需要一个数据 URI 方案流,但现在这似乎很常见。只需将您的回形针变量设置为包含流数据的字符串,其余的由代码处理。
答案 6 :(得分:-1)
我使用类似的技术将图像下拉到回形针
这应该可行,但是未经测试:
io = part.body
def io.original_filename; part.original_file_name || 'unknown-file-name'; end
asset = Asset.new(:email=>email)
asset.asset = io
当我们将IO直接分配给回形针实例时,它需要有一个.original_file_name,这就是我们在第二行中所做的。