@@ -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