Mercurial > hg > soundsoftware-site
comparison app/models/.svn/text-base/custom_field.rb.svn-base @ 0:513646585e45
* Import Redmine trunk SVN rev 3859
author | Chris Cannam |
---|---|
date | Fri, 23 Jul 2010 15:52:44 +0100 |
parents | |
children | 8661b858af72 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:513646585e45 |
---|---|
1 # redMine - project management software | |
2 # Copyright (C) 2006 Jean-Philippe Lang | |
3 # | |
4 # This program is free software; you can redistribute it and/or | |
5 # modify it under the terms of the GNU General Public License | |
6 # as published by the Free Software Foundation; either version 2 | |
7 # of the License, or (at your option) any later version. | |
8 # | |
9 # This program is distributed in the hope that it will be useful, | |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 # GNU General Public License for more details. | |
13 # | |
14 # You should have received a copy of the GNU General Public License | |
15 # along with this program; if not, write to the Free Software | |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 | |
18 class CustomField < ActiveRecord::Base | |
19 has_many :custom_values, :dependent => :delete_all | |
20 acts_as_list :scope => 'type = \'#{self.class}\'' | |
21 serialize :possible_values | |
22 | |
23 validates_presence_of :name, :field_format | |
24 validates_uniqueness_of :name, :scope => :type | |
25 validates_length_of :name, :maximum => 30 | |
26 validates_format_of :name, :with => /^[\w\s\.\'\-]*$/i | |
27 validates_inclusion_of :field_format, :in => Redmine::CustomFieldFormat.available_formats | |
28 | |
29 def initialize(attributes = nil) | |
30 super | |
31 self.possible_values ||= [] | |
32 end | |
33 | |
34 def before_validation | |
35 # make sure these fields are not searchable | |
36 self.searchable = false if %w(int float date bool).include?(field_format) | |
37 true | |
38 end | |
39 | |
40 def validate | |
41 if self.field_format == "list" | |
42 errors.add(:possible_values, :blank) if self.possible_values.nil? || self.possible_values.empty? | |
43 errors.add(:possible_values, :invalid) unless self.possible_values.is_a? Array | |
44 end | |
45 | |
46 # validate default value | |
47 v = CustomValue.new(:custom_field => self.clone, :value => default_value, :customized => nil) | |
48 v.custom_field.is_required = false | |
49 errors.add(:default_value, :invalid) unless v.valid? | |
50 end | |
51 | |
52 # Makes possible_values accept a multiline string | |
53 def possible_values=(arg) | |
54 if arg.is_a?(Array) | |
55 write_attribute(:possible_values, arg.compact.collect(&:strip).select {|v| !v.blank?}) | |
56 else | |
57 self.possible_values = arg.to_s.split(/[\n\r]+/) | |
58 end | |
59 end | |
60 | |
61 def cast_value(value) | |
62 casted = nil | |
63 unless value.blank? | |
64 case field_format | |
65 when 'string', 'text', 'list' | |
66 casted = value | |
67 when 'date' | |
68 casted = begin; value.to_date; rescue; nil end | |
69 when 'bool' | |
70 casted = (value == '1' ? true : false) | |
71 when 'int' | |
72 casted = value.to_i | |
73 when 'float' | |
74 casted = value.to_f | |
75 end | |
76 end | |
77 casted | |
78 end | |
79 | |
80 # Returns a ORDER BY clause that can used to sort customized | |
81 # objects by their value of the custom field. | |
82 # Returns false, if the custom field can not be used for sorting. | |
83 def order_statement | |
84 case field_format | |
85 when 'string', 'text', 'list', 'date', 'bool' | |
86 # COALESCE is here to make sure that blank and NULL values are sorted equally | |
87 "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" + | |
88 " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |
89 " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |
90 " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')" | |
91 when 'int', 'float' | |
92 # Make the database cast values into numeric | |
93 # Postgresql will raise an error if a value can not be casted! | |
94 # CustomValue validations should ensure that it doesn't occur | |
95 "(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" + | |
96 " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |
97 " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |
98 " AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)" | |
99 else | |
100 nil | |
101 end | |
102 end | |
103 | |
104 def <=>(field) | |
105 position <=> field.position | |
106 end | |
107 | |
108 def self.customized_class | |
109 self.name =~ /^(.+)CustomField$/ | |
110 begin; $1.constantize; rescue nil; end | |
111 end | |
112 | |
113 # to move in project_custom_field | |
114 def self.for_all | |
115 find(:all, :conditions => ["is_for_all=?", true], :order => 'position') | |
116 end | |
117 | |
118 def type_name | |
119 nil | |
120 end | |
121 end |