CarrierWave с ActiveResource - PullRequest
       14

CarrierWave с ActiveResource

4 голосов
/ 09 марта 2011

Кто-нибудь знает, как использовать CarrierWave с моделью ActiveResource (в Rails 3)? У меня есть модель ActiveResource с полем для имени файла, и я хочу сохранить файл в удаленной файловой системе.

Я попробовал несколько вещей без особого успеха (или убеждения, что я что-то делал правильно правильно), поэтому я был бы признателен за предложения от любого, кто успешно внедрил CarrierWave без использования модулей ORM, уже включенных в гем.

1 Ответ

9 голосов
/ 29 февраля 2012

Я, вероятно, опаздываю на это, так как первоначальный автор ушел, но этот вопрос поднимается вверх, когда кто-то ищет "activewource для несущей волны", поэтому я подумал, что на него все же стоит ответить.

Для обсуждения давайте предположим, что у нас есть модель с именем 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 сам по себе является моделью, и мы могли бы объявить ее и поиграть с ней, если захотим. На самом деле, вы можете использовать URL, чтобы захватить изображение, если хотите. Но давайте поговорим о загрузке другого изображения.

Мы можем добавить этот небольшой кусочек кода к модели 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 работает.

...