diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 24300c6d2..be9cf550f 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -263,6 +263,8 @@ class CustomField < ActiveRecord::Base end def <=>(field) + return nil unless field.is_a?(CustomField) + position <=> field.position end diff --git a/app/models/enumeration.rb b/app/models/enumeration.rb index 762cddc9a..f2f63372a 100644 --- a/app/models/enumeration.rb +++ b/app/models/enumeration.rb @@ -91,6 +91,8 @@ class Enumeration < ActiveRecord::Base end def <=>(enumeration) + return nil unless enumeration.is_a?(Enumeration) + position <=> enumeration.position end diff --git a/app/models/issue.rb b/app/models/issue.rb index d6d6c7c8b..b037e681c 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1435,6 +1435,8 @@ class Issue < ActiveRecord::Base end def <=>(issue) + return nil unless issue.is_a?(Issue) + if issue.nil? -1 elsif root_id != issue.root_id diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb index 626bb1449..eadb44891 100644 --- a/app/models/issue_category.rb +++ b/app/models/issue_category.rb @@ -43,6 +43,8 @@ class IssueCategory < ActiveRecord::Base end def <=>(category) + return nil unless category.is_a?(IssueCategory) + name <=> category.name end diff --git a/app/models/issue_relation.rb b/app/models/issue_relation.rb index f33b75568..2caaca9ba 100644 --- a/app/models/issue_relation.rb +++ b/app/models/issue_relation.rb @@ -198,6 +198,8 @@ class IssueRelation < ActiveRecord::Base end def <=>(relation) + return nil unless relation.is_a?(IssueRelation) + r = TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order] r == 0 ? id <=> relation.id : r end diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb index c41e7a739..3080fea8a 100644 --- a/app/models/issue_status.rb +++ b/app/models/issue_status.rb @@ -82,6 +82,8 @@ class IssueStatus < ActiveRecord::Base end def <=>(status) + return nil unless status.is_a?(IssueStatus) + position <=> status.position end diff --git a/app/models/member.rb b/app/models/member.rb index 21c623408..9e623d5f3 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -81,6 +81,8 @@ class Member < ActiveRecord::Base end def <=>(member) + return nil unless member.is_a?(Member) + a, b = roles.sort, member.roles.sort if a == b if principal diff --git a/app/models/principal.rb b/app/models/principal.rb index e62b5f320..4cce97e26 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -151,9 +151,11 @@ class Principal < ActiveRecord::Base end def <=>(principal) - if principal.nil? - -1 - elsif self.class.name == principal.class.name + # avoid an error when sorting members without roles (#10053) + return -1 if principal.nil? + return nil unless principal.is_a?(Principal) + + if self.class.name == principal.class.name self.to_s.casecmp(principal.to_s) else # groups after users diff --git a/app/models/project.rb b/app/models/project.rb index a50fa8807..48a34d09d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -671,6 +671,8 @@ class Project < ActiveRecord::Base end def <=>(project) + return nil unless project.is_a?(Project) + name.casecmp(project.name) end diff --git a/app/models/repository.rb b/app/models/repository.rb index be10fa3cf..bc570f2f8 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -141,6 +141,8 @@ class Repository < ActiveRecord::Base end def <=>(repository) + return nil unless repository.is_a?(Repository) + if is_default? -1 elsif repository.is_default? diff --git a/app/models/role.rb b/app/models/role.rb index 604bcd712..078419c60 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -155,14 +155,14 @@ class Role < ActiveRecord::Base end def <=>(role) - if role - if builtin == role.builtin - position <=> role.position - else - builtin <=> role.builtin - end + # returns -1 for nil since r2726 + return -1 if role.nil? + return nil unless role.is_a?(Role) + + if builtin == role.builtin + position <=> role.position else - -1 + builtin <=> role.builtin end end diff --git a/app/models/tracker.rb b/app/models/tracker.rb index bfec75e70..ef2f48b04 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -93,6 +93,8 @@ class Tracker < ActiveRecord::Base def to_s; name end def <=>(tracker) + return nil unless tracker.is_a?(Tracker) + position <=> tracker.position end diff --git a/app/models/version.rb b/app/models/version.rb index f5ac64b74..77228826c 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -316,6 +316,8 @@ class Version < ActiveRecord::Base # Versions are sorted by effective_date and name # Those with no effective_date are at the end, sorted by name def <=>(version) + return nil unless version.is_a?(Version) + if self.effective_date if version.effective_date if self.effective_date == version.effective_date diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb index b7f243354..79e310f31 100644 --- a/lib/redmine/plugin.rb +++ b/lib/redmine/plugin.rb @@ -187,6 +187,8 @@ module Redmine end def <=>(plugin) + return nil unless plugin.is_a?(Plugin) + self.id.to_s <=> plugin.id.to_s end diff --git a/lib/redmine/themes.rb b/lib/redmine/themes.rb index a73184090..ff51f0083 100644 --- a/lib/redmine/themes.rb +++ b/lib/redmine/themes.rb @@ -61,6 +61,8 @@ module Redmine end def <=>(theme) + return nil unless theme.is_a?(Theme) + name <=> theme.name end diff --git a/test/unit/enumeration_test.rb b/test/unit/enumeration_test.rb index 25dfb14c4..a9d0e8eb3 100644 --- a/test/unit/enumeration_test.rb +++ b/test/unit/enumeration_test.rb @@ -179,4 +179,10 @@ class EnumerationTest < ActiveSupport::TestCase override.destroy assert_equal [1, 2, 3], [a, b, c].map(&:reload).map(&:position) end + + def test_spaceship_operator_with_incomparable_value_should_return_nil + e = Enumeration.first + assert_nil e <=> nil + assert_nil e <=> 'foo' + end end