ruby-on-rails - Rails 3.0 在 Heroku 上使用 Paperclip 和 s3 进行图像裁剪

标签 ruby-on-rails ruby-on-rails-3 amazon-s3 paperclip crop

我遇到了一个问题,在其他地方使用 this 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'

照片.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 中发生的情况,我将不胜感激。

谢谢!

最佳答案

问题是否与没有扩展名的文件有关?

例如,当您允许人们提供在您的服务上使用的图像的 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

关于ruby-on-rails - Rails 3.0 在 Heroku 上使用 Paperclip 和 s3 进行图像裁剪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8951948/

相关文章:

ruby - Rspec 加载时间太长

ruby - 在 Rails 中格式化 float 时间

ruby-on-rails - 如何让一行以 | 结尾(管道)在 HAML 中?

ruby-on-rails - 在不覆盖初始化的情况下初始化 ActiveRecord 对象

ruby-on-rails-3 - 在服务器上运行我的 Rails 应用程序

amazon-s3 - AWS EC2 上的 Hbase

ruby-on-rails - 如何使用Carrierwave和Fog检查S3上是否存在镜像版本?

scala - Spark : save and load machine learning model on s3

ruby-on-rails - 具有非唯一列的 Activerecord-import upsert 到 postgres

sql - 在 React 迭代中显示最后一个 child