Class: CustomField

Inherits:
ActiveRecord::Base show all
Defined in:
app/models/custom_field.rb

Overview

redMine - project management software Copyright (C) 2006 Jean-Philippe Lang

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Direct Known Subclasses

DocumentCategoryCustomField, GroupCustomField, IssueCustomField, IssuePriorityCustomField, ProjectCustomField, TimeEntryActivityCustomField, TimeEntryCustomField, UserCustomField, VersionCustomField

Constant Summary

FIELD_FORMATS =
{ "string" => { :name => :label_string, :order => 1 },
                  "text" => { :name => :label_text, :order => 2 },
                  "int" => { :name => :label_integer, :order => 3 },
                  "float" => { :name => :label_float, :order => 4 },
                  "list" => { :name => :label_list, :order => 5 },
            "date" => { :name => :label_date, :order => 6 },
            "bool" => { :name => :label_boolean, :order => 7 }
}.freeze

Class Method Summary

Instance Method Summary

Methods inherited from ActiveRecord::Base

quoted_table_name

Constructor Details

- (CustomField) initialize(attributes = nil)

A new instance of CustomField



38
39
40
41
# File 'app/models/custom_field.rb', line 38

def initialize(attributes = nil)
  super
  self.possible_values ||= []
end

Class Method Details

+ (Object) customized_class



117
118
119
120
# File 'app/models/custom_field.rb', line 117

def self.customized_class
  self.name =~ /^(.+)CustomField$/
  begin; $1.constantize; rescue nil; end
end

+ (Object) for_all

to move in project_custom_field



123
124
125
# File 'app/models/custom_field.rb', line 123

def self.for_all
  find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
end

Instance Method Details

- (Object) <=>(field)



113
114
115
# File 'app/models/custom_field.rb', line 113

def <=>(field)
  position <=> field.position
end

- (Object) before_validation



43
44
45
46
47
# File 'app/models/custom_field.rb', line 43

def before_validation
  # make sure these fields are not searchable
  self.searchable = false if %w(int float date bool).include?(field_format)
  true
end

- (Object) cast_value(value)



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/custom_field.rb', line 70

def cast_value(value)
  casted = nil
  unless value.blank?
    case field_format
    when 'string', 'text', 'list'
      casted = value
    when 'date'
      casted = begin; value.to_date; rescue; nil end
    when 'bool'
      casted = (value == '1' ? true : false)
    when 'int'
      casted = value.to_i
    when 'float'
      casted = value.to_f
    end
  end
  casted
end

- (Object) order_statement

Returns a ORDER BY clause that can used to sort customized objects by their value of the custom field. Returns false, if the custom field can not be used for sorting.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/models/custom_field.rb', line 92

def order_statement
  case field_format
    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
end

- (Object) possible_values=(arg)

Makes possible_values accept a multiline string



62
63
64
65
66
67
68
# File 'app/models/custom_field.rb', line 62

def possible_values=(arg)
  if arg.is_a?(Array)
    write_attribute(:possible_values, arg.compact.collect(&:strip).select {|v| !v.blank?})
  else
    self.possible_values = arg.to_s.split(/[\n\r]+/)
  end
end

- (Object) type_name



127
128
129
# File 'app/models/custom_field.rb', line 127

def type_name
  nil
end

- (Object) validate



49
50
51
52
53
54
55
56
57
58
59
# File 'app/models/custom_field.rb', line 49

def validate
  if self.field_format == "list"
    errors.add(:possible_values, :blank) if self.possible_values.nil? || self.possible_values.empty?
    errors.add(:possible_values, :invalid) unless self.possible_values.is_a? Array
  end
  
  # validate default value
  v = CustomValue.new(:custom_field => self.clone, :value => default_value, :customized => nil)
  v.custom_field.is_required = false
  errors.add(:default_value, :invalid) unless v.valid?
end