Tôi thừa kế một ứng dụng Rails 2.2.2 lưu trữ hình ảnh do người dùng tải lên trên Amazon S3. Mô hình Photo
của attachment_fu dựa trên cung cấp phương thức rotate
sử dụng open-uri
để truy xuất hình ảnh từ S3 và MiniMagick để thực hiện xoay vòng.Tại sao Ruby open-uri lại trả về một StringIO trong bài kiểm thử đơn vị của tôi, nhưng một FileIO trong bộ điều khiển của tôi?
Phương pháp rotate
chứa dòng này để lấy lại hình ảnh để sử dụng với MiniMagick:
temp_image = MiniMagick::Image.from_file(open(self.public_filename).path)
self.public_filename
lợi nhuận giống như
http://s3.amazonaws.com/bucketname/photos/98/photo.jpg
Lấy hình ảnh và xoay nó chỉ làm việc tốt trong ứng dụng đang chạy trong sản xuất và phát triển. Tuy nhiên, các đơn vị kiểm tra không thành công với
TypeError: can't convert nil into String
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `initialize'
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `open'
/Users/santry/Development/totspot/vendor/gems/mini_magick-1.2.3/lib/mini_magick.rb:34:in `from_file'
Lý do là khi các phương pháp mô hình được gọi là trong bối cảnh của bài kiểm tra đơn vị, open(self.public_filename)
được trả lại một đối tượng StringIO
có chứa các dữ liệu hình ảnh. Phương pháp path
trên đối tượng này trả về nil
và MiniMagick::Image.from_file
sẽ thổi lên.
Khi phương thức mô hình rất giống này được gọi từ PhotosController
, open(self.public_filename)
trả về một ví dụ FileIO
được liên kết với một tệp có tên, ví dụ: /tmp/open-uri7378-0
và tệp chứa dữ liệu hình ảnh.
Suy nghĩ nguyên nhân phải có sự khác biệt về môi trường giữa thử nghiệm và phát triển, tôi đã kích hoạt bảng điều khiển trong môi trường phát triển. Nhưng cũng giống như trong thử nghiệm đơn vị, open('http://...')
đã trả về một StringIO
, không phải một FileIO
.
Tôi đã truy tìm theo cách của mình thông qua open-uri và tất cả mã dành riêng cho ứng dụng có liên quan và không tìm thấy lý do nào cho sự khác biệt.
Đừng làm 'mở (self.public_filename) .read', bạn không biết khi nào tay cầm sẽ bị đóng. Sử dụng 'open (self.public_filename, &: read)' thay vào đó, sử dụng block-form và đóng một cách rõ ràng khi hoàn thành. Và nó không thực sự mã hơn. – apeiros
FYI, 'from_blob' hiện không còn được dùng để ưu tiên' đọc'. Xem https://github.com/probablycorey/mini_magick/blob/f309fbf390cd21a845264bca9bec95b9bdae8029/lib/mini_magick.rb#L82 –