带有ActiveResource的CarrierWave

时间:2011-03-09 03:29:32

标签: activeresource carrierwave

有没有人对使用CarrierWave和ActiveResource模型有任何见解(在Rails 3中)?我有一个带文件名字段的ActiveResource模型,我想将文件保存到远程文件系统。

我已经尝试了一些没有太大成功的事情(或者我确信我正在远程正确地做任何事情),所以我很感激任何成功实施CarrierWave的人的建议,而不使用已包含在gem中的ORM模块。

1 个答案:

答案 0 :(得分:9)

我可能已经迟到了,因为原作者继续前进,但当有人搜索“carrierwave activeresource”时,这个问题出现在顶部,所以我认为它仍然值得回答。

为了便于讨论,我们假设我们有一个名为Artist的模型,其中一个名为artist_picture的图片作为CarrierWave上传器安装。使用ActiveRecord,您可以将此图片分配给文件:

artist.artist_picture=File.open('ravello.jpg')

当你保存艺术家时:

artist.save!

图片也会被保存。

现在,假设我创建了一个基于此的资源:

class Artist < ActiveResource::Base
end

如果我随后读了一位艺术家:

artist = Artist.find(1)

然后看看,我会在那里找到它:

#<Artist:0x39432039 @attributes={"id"=>1, "name"=>"Ravello", "artist_picture"=>#<ArtistPicture:0x282347249243 @attributes={"url"=>"/uploads/artists/artist_picture/1/ravello.jpg"}, @prefix_options={}, @persisted=false>, @prefix_options={}, @persisted=false>

有趣的是,artist_picture本身就是一个模型,如果我们想要的话,我们可以声明它并使用它。实际上,如果需要,您可以使用网址抓取图片。但是让我们谈谈上传另一张图片。

我们可以将这一小段代码添加到服务器端的Artist模型中:

  def artist_picture_as_base64=(picsource)
    tmpfile = Tempfile.new(['artist','.jpg'], Rails.root.join('tmp'), :encoding => 'BINARY')
    begin
      tmpfile.write(Base64.decode64(picsource.force_encoding("BINARY")))
      file = CarrierWave::SanitizedFile.new(tmpfile)
      file.content_type = 'image/jpg'
      self.artist_picture = file
    ensure
      tmpfile.close!
    end
  end

我只是展示一个简单的例子 - 您也应该传递原始文件名。无论如何,在资源方面:

class Artist < ActiveResource::Base
  def artist_picture=(filename)
    self.artist_picture_as_base64=Base64.encode64(File.read(filename))
  end
end

此时,在资源方面,您只需将“artist_picture”设置为文件名,它将在保存资源时进行编码和发送。在服务器端,文件将被解码并保存。据推测,你可以通过强制字符串进行二进制编码来跳过base64编码,但是当我这样做时它很糟糕,我没有耐心去追踪它。编码为base64有效。