CarrierWave с ActiveResource

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

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


person tmo256    schedule 09.03.2011    source источник
comment
Это все еще проблема для вас?   -  person Robert    schedule 24.10.2011
comment
Роберт: В некотором смысле; в конце концов я отказался от CarrierWave, потому что решения не было.   -  person tmo256    schedule 02.12.2011


Ответы (1)


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

В целях обсуждения предположим, что у нас есть модель с именем 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 работает.

person Michael Chaney    schedule 28.02.2012
comment
Этот ответ очень полный. Большое Вам спасибо. - person maxiperez; 05.03.2012
comment
Я получаю Encoding::UndefinedConversionError ("\x89" from ASCII-8BIT to UTF-8) только в производстве... - person alexandrecosta; 04.03.2016
comment
Где-то одна из двоичных строк обрабатывается как UTF-8. Какая это линия? - person Michael Chaney; 04.03.2016