バグ #82
完了Redmineで同じ添付ファイルを指すthumbnailマクロを2つ記述すると2つ目でnot foundエラーとなる
100%
説明
thumbnailマクロを同一ファイルに対して2個以上記述すると、2個目で次のエラーとなる(1個目は正常にファイル表示)。
Error executing the thumbnail macro (Attachment farendbasic_wiki 2.png not found)
1st thumbnail points an attachment file with comment.
2nd thumbnail points the attachment file with comment.
Environment: Redmine version 3.4.5.stable.17294 Ruby version 2.3.3-p222 (2016-11-21) [x86_64-linux-gnu] Rails version 4.2.8 Environment production Database adapter Mysql2
本家にバグ登録&パッチを提出しました。
http://www.redmine.org/issues/29038
ファイル
高橋 徹 さんがほぼ7年前に更新
- ファイル default_wiki2.png default_wiki2.png を追加
高橋 徹 さんがほぼ7年前に更新
print debug for Redmine trunk (r17370)
obj.attachments is different in filename shown as follows:
- obj.attachments = #<ActiveRecord::Associations::CollectionProxy [#<Attachment id: 51, container_id: 16, container_type: "Issue", filename: "apollo11_d.jpg", disk_filename: "180617140204_apollo11_d.jpg", filesize: 272888, content_type: "image/jpeg", digest: "78003ea0f1e5d7a8bcd52215763aab0e62663d79e0e66ef5b0...", downloads: 0, author_id: 18, created_on: "2018-06-17 05:02:04", description: "launch satarn five rocket", disk_directory: "2018/06">]>
+ obj.attachments = #<ActiveRecord::Associations::CollectionProxy [#<Attachment id: 51, container_id: 16, container_type: "Issue", filename: "apollo11_d.jpg (launch satarn five rocket)", disk_filename: "180617140204_apollo11_d.jpg", filesize: 272888, content_type: "image/jpeg", digest: "78003ea0f1e5d7a8bcd52215763aab0e62663d79e0e66ef5b0...", downloads: 0, author_id: 18, created_on: "2018-06-17 05:02:04", description: "launch satarn five rocket", disk_directory: "2018/06">]>
thumbnail macro is defined in lib/redmine/wiki_formatting/macros.rb.
メソッドのコールツリーは、p caller
を入れると標準エラー出力される。
macro :thumbnail (macros.rb) exec_macro (macros.rb) inject_macros (application_helper.rb) parse_non_pre_blocks (application_helper.rb) textilizable (application_helper.rb)
同じ画像ファイルのthumbnailを複数埋め込んだ際、2回目の呼び出し時に渡される添付ファイルコレクションのfilename属性が1回目と変換している。
- lib/redmine/wiki_formatting/macros.rb
macro :thumbnail do |obj, args| : puts "[DEBUG] attachment.changes = #{obj.attachments.first.changes}"
とすると、2回目にこのマクロが実行されるときに、次のように属性が変更されていることが判明。
{"filename"=>["apollo11_d.jpg", "apollo11_d.jpg (launch satarn five rocket)"]}
ということで、モデルの属性が変更されている模様。
thumbnailマクロ(macros.rb)の実行文に片っ端からデバッグ文を突っ込みattachmentの内容の変化を確認してみたところ、次の文の前後で変化が発生した。
attachment.title
えっ、信じ難いが、これでfilenameが変わるのである。
puts "@@@@@@@@@@@@ in if block 1b, attachment = #{attachment.inspect}" puts "@@@@@@@@@@@@ attachment.title = #{attachment.title}" puts "@@@@@@@@@@@@ in if block 1c, attachment = #{attachment.inspect}"
このようなデバッグ文を入れて実行すると、
@@@@@@@@@@@@ in if block 1b, attachment = #<Attachment id: 42, container_id: 28, container_type: "GlossaryTerm", filename: "f053.png", disk_filename: "180610070434_f053.png", filesize: 826070, content_type: "image/png", digest: "97eff9f01ba545d05f75fb411a14aaba7346ec80baabad3b66...", downloads: 0, author_id: 18, created_on: "2018-06-09 22:04:34", description: "新規作成時添付", disk_directory: "2018/06"> @@@@@@@@@@@@ attachment.title = f053.png (新規作成時添付) @@@@@@@@@@@@ in if block 1c, attachment = #<Attachment id: 42, container_id: 28, container_type: "GlossaryTerm", filename: "f053.png (新規作成時添付)", disk_filename: "180610070434_f053.png", filesize: 826070, content_type: "image/png", digest: "97eff9f01ba545d05f75fb411a14aaba7346ec80baabad3b66...", downloads: 0, author_id: 18, created_on: "2018-06-09 22:04:34", description: "新規作成時添付", disk_directory: "2018/06">
となり、attachment.titleを参照すると、以降attachment.filenameが引きずられて変わってしまう。
app/models/attachment.rb のtitle周りを調べる
- 1) acts_as_eventで使用
acts_as_event :title => :filename, :url => Proc.new {|o| {:controller => 'attachments', :action => 'show', :id => o.id, :filename => o.fil\ ename}}
- 2) title属性取得メソッドで使用
def title title = filename.to_s if description.present? title << " (#{description})" end title end
ここで、title << " (#{description})"
が実行されると、以降filenameにもdescriptionが追加された文字列となってしまいます。ということは、to_sがもしかするとコピーを返すのではなく、自身を返すのか?と仕様確認してみたとろ、
標準クラス・モジュール > String > to_s
to_sメソッドは、レシーバ自身を返します。
https://ref.xaio.jp/ruby/classes/string/to_s
とある。どうやらこれが原因か!