Class: CustomField

Inherits:
ActiveRecord::Base
  • Object
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.

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 collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = nil) ⇒ 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

.customized_classObject



98
99
100
101
# File 'app/models/custom_field.rb', line 98

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

.for_allObject

to move in project_custom_field



104
105
106
# File 'app/models/custom_field.rb', line 104

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

Instance Method Details

#<=>(field) ⇒ Object



94
95
96
# File 'app/models/custom_field.rb', line 94

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

#before_validationObject



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

#order_statementObject

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.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'app/models/custom_field.rb', line 73

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

#possible_values=(arg) ⇒ Object

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

#type_nameObject



108
109
110
# File 'app/models/custom_field.rb', line 108

def type_name
  nil
end

#validateObject



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