I am uploading an image with a file name containing an umlaut via dragonfly in a Rails 3 app on Heroku. Then I'm trying to display the image using
image_tag @model.image.url, …
In development everything works just fine, but in production I'm getting:
incompatible character encodings: UTF-8 and ASCII-8BIT
.bundle/gems/ruby/1.9.1/gems/actionpack-3.0.7/lib/action_view/helpers/tag_helper.rb:129:in `*'
After reading a bit I've added
E开发者_开发技巧ncoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
in environment.rb
but the problem remains.
What is the proper way to go about this? Do I have to fix the file name when uploading? I was under the impression this should work just fine in Rails 3?
Well, you could try something like url.force_encoding('utf8')
You could also simply sanitize the url in the model before saving it to the database - that's what I did. And, yes, I sometimes stumble over this in the weirdest places, too.
This is what my model looked like:
# encoding: UTF-8
class Page < ActiveRecord::Base
before_save :sanitize_title
private
def sanitize_title
self.title = self.title.force_encoding('UTF-8').downcase.gsub(/[ \-äöüß]/, ' ' => '_', '-' => '_', 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss').gsub(/[^a-z_]/,'')
end
end
This will replace the German umlaute with their ASCII counterparts, convert spaces to underscores and drop everything else.
The first line # encoding: UTF-8
is important or ruby will complain of non-ASCII characters in the model.rb file...
In addition to @Rhywden's answer, here my solution specific for Dragonfly:
image_accessor :image do :after_assign
after_assign{|i| i.name = sanitize_filename(image.name) }
end
def sanitize_filename(filename)
filename.strip.tap do |name|
name.sub! /\A.*(\\|\/)/, ''
name.gsub! /[^\w\.\-]/, '_'
end
end
Details here http://markevans.github.com/dragonfly/file.Models.html and here http://guides.rubyonrails.org/security.html#file-uploads .
精彩评论