Rails 3.0 обрезка изображений с помощью скрепки и s3 на Heroku - PullRequest
2 голосов
/ 21 января 2012

У меня есть проблема, которую я еще не видел в других местах, используя обрезку изображения из этого Railscast

Это в моем производственном приложении, и я получаю это исключение только один раз икакое-то время, и я не смог сам воспроизвести его локально.

Ошибка:

PhotosController# (ActionView::Template::Error) "can't convert nil into String"

/app/.bundle/gems/ruby/1.9.1/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `extname'
/app/.bundle/gems/ruby/1.9.1/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `to_file'
/app/app/models/photo.rb:27:in `photo_geometry'
/app/app/views/photos/show.html.erb:17:in `block in _app_views_photos_show_html_erb__1949294035370253936_41955540__272030757437175302'

photo.rb

  def cropping?  
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?  
  end

  def photo_geometry(style = :original)  
    @geometry ||= {}  
    @geometry[style] ||= Paperclip::Geometry.from_file(photo.to_file(style))  # line #27
  end

show.html.erb

<% content_for(:head) do %>
    <%= stylesheet_link_tag "jquery.Jcrop" %>
    <%= javascript_include_tag "jquery.Jcrop.min" %>
    <script type="text/javascript" charset="utf-8">
        $(function() {
        $('#cropbox').Jcrop({
                onChange: update_crop,  
                onSelect: update_crop,  
                setSelect: [0, 0, 90, 90],  
                aspectRatio: 1
            });
            function update_crop(coords) {
                var rx = 100/coords.w;  
                  var ry = 100/coords.h;  
                  $('#preview').css({  
                    width: Math.round(rx * <%= @photo.photo_geometry(:large).width %>) + 'px',  // line #17
                    height: Math.round(ry * <%= @photo.photo_geometry(:large).height %>) + 'px',  
                    marginLeft: '-' + Math.round(rx * coords.x) + 'px',  
                    marginTop: '-' + Math.round(ry * coords.y) + 'px'  
                  });

              var ratio = <%= @photo.photo_geometry(:original).width %> / <%= @photo.photo_geometry(:large).width %>;   
                  $('#crop_x').val(Math.floor(coords.x * ratio));  
                  $('#crop_y').val(Math.floor(coords.y * ratio));  
                  $('#crop_w').val(Math.floor(coords.w * ratio));  
                  $('#crop_h').val(Math.floor(coords.h * ratio));  
            }
        });
    </script>
<% end %>

Я предполагаю, что проблема связана с тем, что скрепка не в состоянии захватить размеры загруженной фотографии,но, честно говоря, я не очень хорошо понимаю код photo.rb, я просто скопировал его прямо с Railscast.

Есть идеи?Если бы кто-то мог немного лучше объяснить, что происходит в photo.rb, я был бы признателен.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 января 2012

Может быть, проблема связана с файлами без расширения?

Например, когда вы разрешаете пользователям указывать URL-адрес изображения для использования в вашем сервисе и загружаете это изображение для преобразования и хранения на S3, это может означать, что загрузка не имеет расширения, хотя у нее есть тип содержимого и, следовательно, отображается и обрабатывается правильно, как изображение.

Проблема возникает здесь: (см. Комментарии)

 def to_file style = default_style
    return @queued_for_write[style] if @queued_for_write[style]
    filename = path(style)
    extname  = File.extname(filename)           # Likely the Nil is returned here
    basename = File.basename(filename, extname)
    file = Tempfile.new([basename, extname])    # Ext name is used here
    file.binmode
    file.write(AWS::S3::S3Object.value(path(style), bucket_name))
    file.rewind
    return file
  end

Вы можете попробовать следующий патч обезьяны, если расширение действительно вызывает Nil:

module Paperclip
  module Storage
    module S3
      def to_file style = default_style
        return @queued_for_write[style] if @queued_for_write[style]
        filename = path(style)
        extname  = File.extname(filename) || ""          # <==== Changed
        basename = File.basename(filename, extname)
        file = Tempfile.new([basename, extname])   
        file.binmode
        file.write(AWS::S3::S3Object.value(path(style), bucket_name))
        file.rewind
        return file
      end
    end
  end
end
1 голос
/ 02 февраля 2012

Кажется, проблема в разрешении пути для этого стиля.

Как сказал @ahmeij, ваша проблема в следующих строках lib / paperclip / storage / s3.rb: 163

filename = path(style)
extname  = File.extname(filename)

В вашем сообщении об ошибке говорится, что имя файла - Nil, а не String. Это происходит из path метода, который реализован в lib / paperclip / attachment.rb: 139

def path style_name = default_style
  original_filename.nil? ? nil : interpolate(@path, style_name)
end

Это означает, что если у вас нет действительного атрибута _original_filename_ в вашем фото объекте, это будет значение Nil .

=> Вам нужно понять, почему этот атрибут может быть недействительным

...