Class: Skyline::Content::MetaData::Field

Inherits:
OpenStruct
  • Object
show all
Defined in:
lib/skyline/content/meta_data/field.rb

Overview

:nodoc:

Direct Known Subclasses

ClassSettings

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*params) ⇒ Field

Returns a new instance of Field.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/skyline/content/meta_data/field.rb', line 15

def initialize(*params)
  super(*params)
  
  # Set implicit association data.
  if self.owner_class && reflection = self.owner_class.reflect_on_association(self.name)
    self.reflection = reflection
    self.hidden = [:edit,:create] unless self.editor || !self.hidden.nil?
  end
  
  # Check if this was a filterable field and check if:
  # * this field is a column
  # * this field is a belongs_to association
  if self.respond_to?(:filterable) && self.filterable && (!self.owner_class.column_names.include?(self.name.to_s) && (!self.association? || self.reflection.macro != :belongs_to))
    raise ArgumentError, "Cannot use filter on non-database field."
  end
  
  # Set default editors if it's not set but type is available
  if !self.respond_to?(:editor) || self.editor.blank?
    self.editor = {
      :string => :text_field,
      :boolean => :boolean,
      :datetime => :date_time,
      :timestamp  => :date_time,
      :date => :date,
      :text => :textarea
    }[self.type]
  end
end

Class Method Details

.from(field, options) ⇒ Object



8
9
10
11
12
# File 'lib/skyline/content/meta_data/field.rb', line 8

def from(field,options)
  table = field.instance_variable_get(:@table)
  options.delete(:name)
  new(table.dup.update(options))
end

Instance Method Details

#association?Boolean

Is this field an association

Returns

Boolean

Wether or not this is an association

Returns:

  • (Boolean)


72
73
74
# File 'lib/skyline/content/meta_data/field.rb', line 72

def association?
  self.respond_to?(:reflection) && !self.reflection.nil?
end

#attribute_nameObject

The method/column name this field writes to. This takes foreign_keys of belongs_to associations in account.



101
102
103
# File 'lib/skyline/content/meta_data/field.rb', line 101

def attribute_name
  self.association? && self.reflection.macro == :belongs_to && self.reflection.foreign_key || self.name
end

#attribute_value(record) ⇒ Object

Raises:

  • (ArgumentError)


151
152
153
154
155
# File 'lib/skyline/content/meta_data/field.rb', line 151

def attribute_value(record)
  raise(ArgumentError, "The record class (#{record.class}) and the field class (#{self.owner_class}) do not match") if !record.kind_of?(self.owner_class)
  raise(ArgumentError, "The record does not respond do this field name (#{self.name})") unless record.respond_to?(self.name)
  record.send(self.attribute_name)      
end

#columnObject

The ActiveRecord::Column object this field is related to. If empty this can be a virtual field or a field defined through a method.

Returns

ActiveRecord::Column,nil

The column object if any.



82
83
84
# File 'lib/skyline/content/meta_data/field.rb', line 82

def column
  self.owner && self.owner.respond_to?(:columns_hash) && self.owner.columns_hash[self.name.to_s]
end

#hidden_in(scope) ⇒ Object



157
158
159
# File 'lib/skyline/content/meta_data/field.rb', line 157

def hidden_in(scope)
  self.respond_to?(:hidden) && (self.hidden == true || self.hidden.include?(scope))      
end

#inspectObject



202
203
204
# File 'lib/skyline/content/meta_data/field.rb', line 202

def inspect
  "<Field @table=#{@table.inspect}>"
end

#klassObject

Functions below only needed on fields with serialized attributes



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/skyline/content/meta_data/field.rb', line 166

def klass
  case self.type
    when :integer       then Fixnum
    when :float         then Float
    when :decimal       then BigDecimal
    when :datetime      then Time
    when :date          then Date
    when :timestamp     then Time
    when :time          then Time
    when :text, :string then String
    when :binary        then String
    when :boolean       then Object
    else nil
  end
end

#ownerObject



132
133
134
# File 'lib/skyline/content/meta_data/field.rb', line 132

def owner
  method_missing(:owner)
end

#owner_classObject



136
137
138
139
140
141
142
143
# File 'lib/skyline/content/meta_data/field.rb', line 136

def owner_class
  if self.owner && self.owner.kind_of?(Class) && self.owner.ancestors.include?(ActiveRecord::Base)
    self.owner
  elsif self.owner
    # This is a group so we get the group's owner
    self.owner.owner
  end
end

#plural(value, alternative = nil) ⇒ Object



62
63
64
65
# File 'lib/skyline/content/meta_data/field.rb', line 62

def plural(value,alternative=nil)
  return alternative.to_s.humanize.pluralize if value.nil?    
  value.kind_of?(Array) && value.last || value.to_s.pluralize
end

#plural_label(alt = self.name) ⇒ Object



53
54
55
# File 'lib/skyline/content/meta_data/field.rb', line 53

def plural_label(alt=self.name)
  plural(self.label,alt)    
end

#plural_titleObject



47
48
49
# File 'lib/skyline/content/meta_data/field.rb', line 47

def plural_title
  plural(self.title,self.plural_label)
end

#singular(value, alternative = nil) ⇒ Object



57
58
59
60
# File 'lib/skyline/content/meta_data/field.rb', line 57

def singular(value,alternative=nil)
  return alternative.to_s.humanize if value.nil?    
  value.kind_of?(Array) && value.first || value.to_s
end

#singular_label(alt = self.name) ⇒ Object



50
51
52
# File 'lib/skyline/content/meta_data/field.rb', line 50

def singular_label(alt=self.name)
  singular(self.label,alt)
end

#singular_titleObject



44
45
46
# File 'lib/skyline/content/meta_data/field.rb', line 44

def singular_title
  singular(self.title,self.singular_label)
end

#to_paramObject



206
207
208
# File 'lib/skyline/content/meta_data/field.rb', line 206

def to_param
  self.name
end

#typeObject

The type of the associated column, or if it’s serialized the type that this serialized field was defined as.

Returns

Symbol

The type name can by any of:

*  :string   
*  :text     
*  :integer  
*  :float    
*  :decimal  
*  :datetime 
*  :timestamp
*  :time     
*  :date     
*  :binary   
*  :boolean



123
124
125
126
127
128
129
130
# File 'lib/skyline/content/meta_data/field.rb', line 123

def type
  type = method_missing(:type)
  if type.kind_of?(Class) || type.blank?
    self.column && self.column.type
  else
    type
  end
end

#type_cast(value) ⇒ Object

Casts value (which is a String) to an appropriate instance. Only needed on fields that are in serialized data.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/skyline/content/meta_data/field.rb', line 184

def type_cast(value)
  return nil if value.nil?
  case self.type
    when :string    then value
    when :text      then value
    when :integer   then value.to_i rescue value ? 1 : 0
    when :float     then value.to_f
    when :decimal   then ActiveRecord::ConnectionAdapters::Column.value_to_decimal(value)
    when :datetime  then ActiveRecord::ConnectionAdapters::Column.string_to_time(value)
    when :timestamp then ActiveRecord::ConnectionAdapters::Column.string_to_time(value)
    when :time      then ActiveRecord::ConnectionAdapters::Column.string_to_dummy_time(value)
    when :date      then ActiveRecord::ConnectionAdapters::Column.string_to_date(value)
    when :binary    then ActiveRecord::ConnectionAdapters::Column.binary_to_string(value)
    when :boolean   then ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
    else value
  end
end

#unique_valuesObject

Gets all unique values for this field on the owner_class. Returns arrays usable in select/options_for_select helpers.

Returns

Array[String,Array]

Array of values. If this is an association we get an array of [id,title]



92
93
94
95
96
97
98
# File 'lib/skyline/content/meta_data/field.rb', line 92

def unique_values
  if self.association?
    self.reflection.klass.find(:all).map{|a| [a.human_id,a.id] }
  else
    self.owner_class.connection.select_values("SELECT DISTINCT(#{self.name}) FROM #{self.owner_class.table_name}")
  end
end

#update(options = {}) ⇒ Object



161
162
163
# File 'lib/skyline/content/meta_data/field.rb', line 161

def update(options={})
  options.each{|value, key| self.send("#{key}=",value)}
end

#value(record) ⇒ Object

Raises:

  • (ArgumentError)


145
146
147
148
149
# File 'lib/skyline/content/meta_data/field.rb', line 145

def value(record)
  raise(ArgumentError, "The record class (#{record.class}) and the field class (#{self.owner_class}) do not match") if !record.kind_of?(self.owner_class)
  raise(ArgumentError, "The record does not respond do this field name (#{self.name})") unless record.respond_to?(self.name)
  record.send(self.name)
end