【问题标题】:Rails 3 + paperclip + windows + file name encoding problemRails 3 + 回形针 + windows + 文件名编码问题
【发布时间】:2011-06-08 11:45:07
【问题描述】:

我使用 rails 3paperclip 插件来附加文件。

我有两个模型:

  • 订单;
  • 订单附件:
    • belongs_to :order;
    • has_attached_file :doc;

我尝试通过回形针将文件附加到订单中;

当我使用英文或数字文件名附加文件时,一切都很好

  SQL (0.0ms)  INSERT INTO "order_attachments" ("order_id", "created_at", "updated_at",  "doc_file_name", "doc_content_type", "doc_file_size", "doc_updated_at") VALUES (1, '2011-06-08 11:07:22.108523', '2011-06-08 11:07:22.108523', 'Example.txt', 'text/plain', 22, '2011-06-08 11:07:22.105523') RETURNING "id"
[paperclip] Saving attachments.
[paperclip] saving D:/my_project_path/public/system/docs/93/original/Example.txt
  SQL (1.0ms)  COMMIT
Completed 200 OK in 229ms (Views: 21.0ms | ActiveRecord: 7.0ms)

但是当我附加带有俄罗斯文件名的文件时,发生错误

SQL (1.0ms)  INSERT INTO "order_attachments" ("order_id", "created_at", "updated_at", "doc_file_name", "doc_content_type", "doc_file_size", "doc_updated_at") VALUES (1, '2011-06-08 11:26:43.040925', '2011-06-08 11:26:43.040925', 'Пример.txt', 'text/plain', 26, '2011-06-08 11:26:43.035924') RETURNING "id"
[paperclip] Saving attachments.
[paperclip] saving D:/my_project_path/public/system/docs/94/original/Пример.txt
  SQL (0.0ms)  ROLLBACK
Completed   in 161ms

Errno::ENOENT (No such file or directory - D:/my_project_path/public/system/docs/94/original/╨а╤Я╨б╨В╨а╤С╨а╤Ш╨а┬╡╨б╨В.txt):
  app/controllers/orders_controller.rb:138:in `attachment'

回形针保存文件到 D:/my_project_path/public/system/docs/94/original/Пример.txt(我可以通过资源管理器打开它)但数据库中没有创建记录。可能是编码有问题。

我用:

  • Windows 7 专业版 x64;
  • PostgreSQL 9.0(UTF-8 数据库编码);
  • Ruby 1.9.2;
  • Ruby on Rails 3.0.7;
  • 回形针 2.3.11;

感谢您的帮助。

【问题讨论】:

  • 从 'Пример.txt' 到 "╨а╤Я╨б╨В╨а╤С╨а╤Ш╨а┬╡╨б╨В.txt" » 绝对是编码问题。

标签: windows ruby-on-rails-3 paperclip


【解决方案1】:

正如我所说的回形针保存附加文件,rails 创建有效请求,但回形针源中的某些内容在 Windows 下出现问题。

Errno::ENOENT 异常在 C:\Ruby192\lib\ruby\gems\1.9.1\gems\paperclip-2.3.11\lib\paperclip\storage\ 中被捕获第 42 行

中的 filesystem.rb 源文件
def flush_writes #:nodoc:
  @queued_for_write.each do |style_name, file|
    file.close
    FileUtils.mkdir_p(File.dirname(path(style_name)))
    log("saving #{path(style_name)}")
    FileUtils.mv(file.path, path(style_name))
    FileUtils.chmod(0644, path(style_name))
  end
  @queued_for_write = {}
end

我把这个函数改成:

def flush_writes #:nodoc:
  @queued_for_write.each do |style_name, file|
    file.close
    FileUtils.mkdir_p(File.dirname(path(style_name)))
    log("saving #{path(style_name)}")
    FileUtils.mv(file.path, path(style_name))
    begin
      FileUtils.chmod(0644, path(style_name))
    rescue Errno::ENOENT
      log("Errno::ENOENT caught on #{ENV['OS']}")
    end
  end
  @queued_for_write = {}
end

这个解决方案对我有用。现在服务器日志输出是:

  SQL (1.0ms)  INSERT INTO "order_attachments" ("order_id", "created_at", "updated_at", "doc_file_name", "doc_content_type", "doc_file_size", "doc_updated_at") VALUES (14, '2011-06-08 18:44:25.853559', '2011-06-08 18:44:25.853559', 'Пример.doc', 'application/msword', 292352, '2011-06-08 18:44:25.727552') RETURNING "id"
[paperclip] Saving attachments.
[paperclip] saving D:/my_project_path/public/system/docs/199/original/Пример.doc
[paperclip] Errno::ENOENT caught on Windows_NT    --> !!! here it is - our exception !!!
  SQL (3.0ms)  COMMIT
Completed 200 OK in 287ms (Views: 13.0ms | ActiveRecord: 15.0ms)

【讨论】:

    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2015-06-26
    相关资源
    最近更新 更多