git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2258 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.9.0
@@ -65,12 +65,20 @@ class CustomField < ActiveRecord::Base | |||
# Returns false, if the custom field can not be used for sorting. | |||
def order_statement | |||
case field_format | |||
when 'string', 'list', 'date', 'bool' | |||
when 'string', 'text', 'list', 'date', 'bool' | |||
# COALESCE is here to make sure that blank and NULL values are sorted equally | |||
"COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" + | |||
" WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |||
" AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |||
" AND cv_sort.custom_field_id=#{id} LIMIT 1), '')" | |||
when 'int', 'float' | |||
# Make the database cast values into numeric | |||
# Postgresql will raise an error if a value can not be casted! | |||
# CustomValue validations should ensure that it doesn't occur | |||
"(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" + | |||
" WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |||
" AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |||
" AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)" | |||
else | |||
nil | |||
end |
@@ -69,4 +69,16 @@ custom_fields_005: | |||
is_required: false | |||
field_format: float | |||
default_value: "" | |||
custom_fields_006: | |||
name: Float field | |||
min_length: 0 | |||
regexp: "" | |||
is_for_all: true | |||
type: IssueCustomField | |||
max_length: 0 | |||
possible_values: "" | |||
id: 6 | |||
is_required: false | |||
field_format: float | |||
default_value: "" | |||
@@ -8,3 +8,12 @@ custom_fields_trackers_002: | |||
custom_fields_trackers_003: | |||
custom_field_id: 2 | |||
tracker_id: 3 | |||
custom_fields_trackers_004: | |||
custom_field_id: 6 | |||
tracker_id: 1 | |||
custom_fields_trackers_005: | |||
custom_field_id: 6 | |||
tracker_id: 2 | |||
custom_fields_trackers_006: | |||
custom_field_id: 6 | |||
tracker_id: 3 |
@@ -3,54 +3,84 @@ custom_values_006: | |||
customized_type: Issue | |||
custom_field_id: 2 | |||
customized_id: 3 | |||
id: 9 | |||
id: 6 | |||
value: "125" | |||
custom_values_007: | |||
customized_type: Project | |||
custom_field_id: 3 | |||
customized_id: 1 | |||
id: 10 | |||
id: 7 | |||
value: Stable | |||
custom_values_001: | |||
customized_type: User | |||
custom_field_id: 4 | |||
customized_id: 3 | |||
id: 2 | |||
id: 1 | |||
value: "" | |||
custom_values_002: | |||
customized_type: User | |||
custom_field_id: 4 | |||
customized_id: 4 | |||
id: 3 | |||
id: 2 | |||
value: 01 23 45 67 89 | |||
custom_values_003: | |||
customized_type: User | |||
custom_field_id: 4 | |||
customized_id: 2 | |||
id: 4 | |||
id: 3 | |||
value: "" | |||
custom_values_004: | |||
customized_type: Issue | |||
custom_field_id: 2 | |||
customized_id: 1 | |||
id: 7 | |||
id: 4 | |||
value: "125" | |||
custom_values_005: | |||
customized_type: Issue | |||
custom_field_id: 2 | |||
customized_id: 2 | |||
id: 8 | |||
id: 5 | |||
value: "" | |||
custom_values_008: | |||
customized_type: Issue | |||
custom_field_id: 1 | |||
customized_id: 3 | |||
id: 11 | |||
id: 8 | |||
value: "MySQL" | |||
custom_values_009: | |||
customized_type: Issue | |||
custom_field_id: 2 | |||
customized_id: 3 | |||
id: 12 | |||
id: 9 | |||
value: "this is a stringforcustomfield search" | |||
custom_values_010: | |||
customized_type: Issue | |||
custom_field_id: 6 | |||
customized_id: 1 | |||
id: 10 | |||
value: "2.1" | |||
custom_values_011: | |||
customized_type: Issue | |||
custom_field_id: 6 | |||
customized_id: 2 | |||
id: 11 | |||
value: "2.05" | |||
custom_values_012: | |||
customized_type: Issue | |||
custom_field_id: 6 | |||
customized_id: 3 | |||
id: 12 | |||
value: "11.65" | |||
custom_values_013: | |||
customized_type: Issue | |||
custom_field_id: 6 | |||
customized_id: 7 | |||
id: 13 | |||
value: "" | |||
custom_values_014: | |||
customized_type: Issue | |||
custom_field_id: 6 | |||
customized_id: 5 | |||
id: 14 | |||
value: "-7.6" | |||
@@ -185,6 +185,7 @@ class QueryTest < Test::Unit::TestCase | |||
:conditions => q.statement, | |||
:order => "#{c.sortable} ASC" | |||
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | |||
assert !values.empty? | |||
assert_equal values.sort, values | |||
end | |||
@@ -198,9 +199,24 @@ class QueryTest < Test::Unit::TestCase | |||
:conditions => q.statement, | |||
:order => "#{c.sortable} DESC" | |||
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | |||
assert !values.empty? | |||
assert_equal values.sort.reverse, values | |||
end | |||
def test_sort_by_float_custom_field_asc | |||
q = Query.new | |||
c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' } | |||
assert c | |||
assert c.sortable | |||
issues = Issue.find :all, | |||
:include => [ :assigned_to, :status, :tracker, :project, :priority ], | |||
:conditions => q.statement, | |||
:order => "#{c.sortable} ASC" | |||
values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact | |||
assert !values.empty? | |||
assert_equal values.sort, values | |||
end | |||
def test_label_for | |||
q = Query.new | |||
assert_equal 'assigned_to', q.label_for('assigned_to_id') |