##// END OF EJS Templates
Ability to sort the issue list by text, list, date and boolean custom fields (#1139)....
Jean-Philippe Lang -
r2255:3a28848ca03a
parent child
Show More
@@ -59,11 +59,32 class CustomField < ActiveRecord::Base
59 v.custom_field.is_required = false
59 v.custom_field.is_required = false
60 errors.add(:default_value, :activerecord_error_invalid) unless v.valid?
60 errors.add(:default_value, :activerecord_error_invalid) unless v.valid?
61 end
61 end
62
63 # Returns a ORDER BY clause that can used to sort customized
64 # objects by their value of the custom field.
65 # Returns false, if the custom field can not be used for sorting.
66 def order_statement
67 case field_format
68 when 'string', 'list', 'date', 'bool'
69 # COALESCE is here to make sure that blank and NULL values are sorted equally
70 "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" +
71 " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" +
72 " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
73 " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')"
74 else
75 nil
76 end
77 end
62
78
63 def <=>(field)
79 def <=>(field)
64 position <=> field.position
80 position <=> field.position
65 end
81 end
66
82
83 def self.customized_class
84 self.name =~ /^(.+)CustomField$/
85 begin; $1.constantize; rescue nil; end
86 end
87
67 # to move in project_custom_field
88 # to move in project_custom_field
68 def self.for_all
89 def self.for_all
69 find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
90 find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
@@ -30,6 +30,10 class CustomValue < ActiveRecord::Base
30 self.value == '1'
30 self.value == '1'
31 end
31 end
32
32
33 def to_s
34 value.to_s
35 end
36
33 protected
37 protected
34 def validate
38 def validate
35 if value.blank?
39 if value.blank?
@@ -35,7 +35,7 class QueryCustomFieldColumn < QueryColumn
35
35
36 def initialize(custom_field)
36 def initialize(custom_field)
37 self.name = "cf_#{custom_field.id}".to_sym
37 self.name = "cf_#{custom_field.id}".to_sym
38 self.sortable = false
38 self.sortable = custom_field.order_statement || false
39 @cf = custom_field
39 @cf = custom_field
40 end
40 end
41
41
@@ -175,6 +175,32 class QueryTest < Test::Unit::TestCase
175 assert q.has_column?(c)
175 assert q.has_column?(c)
176 end
176 end
177
177
178 def test_sort_by_string_custom_field_asc
179 q = Query.new
180 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
181 assert c
182 assert c.sortable
183 issues = Issue.find :all,
184 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
185 :conditions => q.statement,
186 :order => "#{c.sortable} ASC"
187 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
188 assert_equal values.sort, values
189 end
190
191 def test_sort_by_string_custom_field_desc
192 q = Query.new
193 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
194 assert c
195 assert c.sortable
196 issues = Issue.find :all,
197 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
198 :conditions => q.statement,
199 :order => "#{c.sortable} DESC"
200 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
201 assert_equal values.sort.reverse, values
202 end
203
178 def test_label_for
204 def test_label_for
179 q = Query.new
205 q = Query.new
180 assert_equal 'assigned_to', q.label_for('assigned_to_id')
206 assert_equal 'assigned_to', q.label_for('assigned_to_id')
General Comments 0
You need to be logged in to leave comments. Login now