diff --git a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb index acddf5fa9..344ff0866 100644 --- a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb +++ b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb @@ -30,7 +30,7 @@ module Redmine attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym has_many :attachments, options.merge(:as => :container, - :order => "#{Attachment.table_name}.created_on", + :order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC", :dependent => :destroy) send :include, Redmine::Acts::Attachable::InstanceMethods before_save :attach_saved_attachments @@ -62,7 +62,19 @@ module Redmine def save_attachments(attachments, author=User.current) if attachments.is_a?(Hash) - attachments = attachments.values + attachments = attachments.stringify_keys + attachments = attachments.to_a.sort {|a, b| + if a.first.to_i > 0 && b.first.to_i > 0 + a.first.to_i <=> b.first.to_i + elsif a.first.to_i > 0 + 1 + elsif b.first.to_i > 0 + -1 + else + a.first <=> b.first + end + } + attachments = attachments.map(&:last) end if attachments.is_a?(Array) attachments.each do |attachment| diff --git a/test/object_helpers.rb b/test/object_helpers.rb index 0100a8bed..3a7a0deba 100644 --- a/test/object_helpers.rb +++ b/test/object_helpers.rb @@ -61,6 +61,8 @@ module ObjectHelpers def Issue.generate!(attributes={}) issue = Issue.new(attributes) + issue.project ||= Project.find(1) + issue.tracker ||= issue.project.trackers.first issue.subject = 'Generated' if issue.subject.blank? issue.author ||= User.find(2) yield issue if block_given? diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index fc08313bc..d192a34f8 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -1576,4 +1576,18 @@ class IssueTest < ActiveSupport::TestCase def test_journals_after_with_blank_arg_should_return_all_journals assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('') end + + def test_save_attachments_with_hash_should_save_attachments_in_keys_order + set_tmp_attachments_directory + issue = Issue.generate! + issue.save_attachments({ + 'p0' => {'file' => mock_file_with_options(:original_filename => 'upload')}, + '3' => {'file' => mock_file_with_options(:original_filename => 'bar')}, + '1' => {'file' => mock_file_with_options(:original_filename => 'foo')} + }) + issue.attach_saved_attachments + + assert_equal 3, issue.reload.attachments.count + assert_equal %w(upload foo bar), issue.attachments.map(&:filename) + end end