Class: ActiveScaffold::DataStructures::Column

Inherits:
Object
  • Object
show all
Includes:
Configurable, OrmChecks
Defined in:
lib/active_scaffold/data_structures/column.rb

Constant Summary collapse

NO_PARAMS =
Set.new.freeze
NO_OPTIONS =
{}.freeze
@@associated_limit =
3
@@associated_number =
true
@@show_blank_record =
true
%i[new edit show]
@@association_form_ui =
nil

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from OrmChecks

active_record?, column_type, columns, columns_hash, content_columns, mongoid?, quoted_table_name, reflect_on_all_associations, table_name, tableless?, type_for_attribute

Methods included from Configurable

#configure, #method_missing, #respond_to_missing?

Constructor Details

#initialize(name, active_record_class, delegated_association = nil) ⇒ Column

instantiation is handled internally through the DataStructures::Columns object


309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/active_scaffold/data_structures/column.rb', line 309

def initialize(name, active_record_class, delegated_association = nil) #:nodoc:
  @name = name.to_sym
  @active_record_class = active_record_class
  @column = _columns_hash[name.to_s]
  @delegated_association = delegated_association
  @cache_key = [@active_record_class.name, name].compact.map(&:to_s).join('#')
  setup_association_info

  @link = nil
  @autolink = association.present?
  @table = _table_name
  @associated_limit = self.class.associated_limit
  @associated_number = self.class.associated_number
  @show_blank_record = self.class.show_blank_record
  @send_form_on_update_column = self.class.send_form_on_update_column
  @actions_for_association_links = self.class.actions_for_association_links.dup if association
  @select_columns = default_select_columns

  @text = @column.nil? || [:string, :text, String].include?(column_type)
  @number = false
  if @column
    if active_record_class.respond_to?(:defined_enums) && active_record_class.defined_enums[name.to_s]
      @form_ui = :select
      @options = {:options => active_record_class.send(name.to_s.pluralize).keys.map(&:to_sym)}
    elsif column_number?
      @number = true
      @form_ui = :number
      @options = {:format => :i18n_number}
    else
      @form_ui =
        case @column.type
        when :boolean then :checkbox
        when :text then :textarea
        end
    end
  end
  @allow_add_existing = true
  @form_ui = self.class.association_form_ui if @association && self.class.association_form_ui

  self.includes = [association.name] if association&.allow_join?
  if delegated_association
    self.includes = includes ? [delegated_association.name => includes] : [delegated_association.name]
  end
  self.search_joins = includes.clone if includes

  # default all the configurable variables
  self.css_class = ''
  self.required = active_record_class.validators_on(name).any? do |val|
    validator_force_required?(val)
  end
  self.sort = true
  self.search_sql = true

  @weight = estimate_weight
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ActiveScaffold::Configurable

Instance Attribute Details

Returns the value of attribute actions_for_association_links


259
260
261
# File 'lib/active_scaffold/data_structures/column.rb', line 259

def actions_for_association_links
  @actions_for_association_links
end

#active_record_classObject (readonly) Also known as: model

Returns the value of attribute active_record_class


8
9
10
# File 'lib/active_scaffold/data_structures/column.rb', line 8

def active_record_class
  @active_record_class
end

#allow_add_existingObject

Whether to enable add_existing for this column


29
30
31
# File 'lib/active_scaffold/data_structures/column.rb', line 29

def allow_add_existing
  @allow_add_existing
end

#associated_limitObject

Returns the value of attribute associated_limit


233
234
235
# File 'lib/active_scaffold/data_structures/column.rb', line 233

def associated_limit
  @associated_limit
end

#associated_number=(value) ⇒ Object (writeonly)

Sets the attribute associated_number

Parameters:

  • value

    the value to set the attribute associated_number to.


238
239
240
# File 'lib/active_scaffold/data_structures/column.rb', line 238

def associated_number=(value)
  @associated_number = value
end

#associationObject (readonly)

the association from the ActiveRecord class


272
273
274
# File 'lib/active_scaffold/data_structures/column.rb', line 272

def association
  @association
end

#association_join_textObject

what string to use to join records from plural associations


244
245
246
# File 'lib/active_scaffold/data_structures/column.rb', line 244

def association_join_text
  @association_join_text
end

#cache_keyObject (readonly)

cache key to cache column info


306
307
308
# File 'lib/active_scaffold/data_structures/column.rb', line 306

def cache_key
  @cache_key
end

#calculateObject

define a calculation for the column. anything that ActiveRecord::Calculations::ClassMethods#calculate accepts will do.


172
173
174
# File 'lib/active_scaffold/data_structures/column.rb', line 172

def calculate
  @calculate
end

#collapsedObject

Whether this column set is collapsed by default in contexts where collapsing is supported


26
27
28
# File 'lib/active_scaffold/data_structures/column.rb', line 26

def collapsed
  @collapsed
end

#columnObject (readonly)

the ConnectionAdapter::*Column object from the ActiveRecord class


269
270
271
# File 'lib/active_scaffold/data_structures/column.rb', line 269

def column
  @column
end

#css_classObject

this will be /joined/ to the :name for the td's class attribute. useful if you want to style columns on different ActiveScaffolds the same way, but the columns have different names.


64
65
66
# File 'lib/active_scaffold/data_structures/column.rb', line 64

def css_class
  @css_class
end

#delegated_associationObject (readonly)

the singular association which this column belongs to


275
276
277
# File 'lib/active_scaffold/data_structures/column.rb', line 275

def delegated_association
  @delegated_association
end

#descriptionObject


49
50
51
52
53
54
55
# File 'lib/active_scaffold/data_structures/column.rb', line 49

def description
  if @description
    @description
  else
    I18n.t name, :scope => [:activerecord, :description, active_record_class.to_s.underscore.to_sym], :default => ''
  end
end

#form_uiObject

supported options:

* for association columns
  * :select - displays a simple <select> or a collection of checkboxes to (dis)associate records

117
118
119
# File 'lib/active_scaffold/data_structures/column.rb', line 117

def form_ui
  @form_ui
end

#includesObject

a collection of associations to pre-load when finding the records on a page


180
181
182
# File 'lib/active_scaffold/data_structures/column.rb', line 180

def includes
  @includes
end

#inplace_editObject

Whether to enable inplace editing for this column. Currently works for text columns, in the List.


15
16
17
# File 'lib/active_scaffold/data_structures/column.rb', line 15

def inplace_edit
  @inplace_edit
end

#inplace_edit_updateObject

:table to refresh list true or :row to refresh row


23
24
25
# File 'lib/active_scaffold/data_structures/column.rb', line 23

def inplace_edit_update
  @inplace_edit_update
end

#labelObject


43
44
45
# File 'lib/active_scaffold/data_structures/column.rb', line 43

def label
  as_(@label) || active_record_class.human_attribute_name(name.to_s)
end

#list_uiObject


121
122
123
# File 'lib/active_scaffold/data_structures/column.rb', line 121

def list_ui
  @list_ui || form_ui
end

#nameObject (readonly)

this is the name of the getter on the ActiveRecord model. it is the only absolutely required attribute … all others will be inferred from this name.


12
13
14
# File 'lib/active_scaffold/data_structures/column.rb', line 12

def name
  @name
end

#number=(value) ⇒ Object (writeonly)

Sets the attribute number

Parameters:

  • value

    the value to set the attribute number to.


282
283
284
# File 'lib/active_scaffold/data_structures/column.rb', line 282

def number=(value)
  @number = value
end

#optionsObject


137
138
139
140
# File 'lib/active_scaffold/data_structures/column.rb', line 137

def options
  return @options || NO_OPTIONS if frozen?
  @options ||= NO_OPTIONS.dup
end

#placeholderObject


59
60
61
# File 'lib/active_scaffold/data_structures/column.rb', line 59

def placeholder
  @placeholder || I18n.t(name, :scope => [:activerecord, :placeholder, active_record_class.to_s.underscore.to_sym], :default => '')
end

#required=(value) ⇒ Object (writeonly)

whether the field is required or not. used on the form for visually indicating the fact to the user. TODO: move into predicate


68
69
70
# File 'lib/active_scaffold/data_structures/column.rb', line 68

def required=(value)
  @required = value
end

#search_uiObject


131
132
133
# File 'lib/active_scaffold/data_structures/column.rb', line 131

def search_ui
  @search_ui || @form_ui || (:select if association && !association.polymorphic?)
end

#select_associated_columnsObject

a collection of columns to load when eager loading is disabled, if it's nil all columns will be loaded


203
204
205
# File 'lib/active_scaffold/data_structures/column.rb', line 203

def select_associated_columns
  @select_associated_columns
end

#select_columnsObject

What columns load from main table


32
33
34
# File 'lib/active_scaffold/data_structures/column.rb', line 32

def select_columns
  @select_columns
end

#send_form_on_update_columnObject

Returns the value of attribute send_form_on_update_column


84
85
86
# File 'lib/active_scaffold/data_structures/column.rb', line 84

def send_form_on_update_column
  @send_form_on_update_column
end

#show_blank_record=(value) ⇒ Object (writeonly)

Sets the attribute show_blank_record

Parameters:

  • value

    the value to set the attribute show_blank_record to.


249
250
251
# File 'lib/active_scaffold/data_structures/column.rb', line 249

def show_blank_record=(value)
  @show_blank_record = value
end

#show_uiObject


126
127
128
# File 'lib/active_scaffold/data_structures/column.rb', line 126

def show_ui
  @show_ui || list_ui
end

#update_columnsObject

Returns the value of attribute update_columns


73
74
75
# File 'lib/active_scaffold/data_structures/column.rb', line 73

def update_columns
  @update_columns
end

#weightObject

to modify the default order of columns


228
229
230
# File 'lib/active_scaffold/data_structures/column.rb', line 228

def weight
  @weight
end

Instance Method Details

#<=>(other) ⇒ Object


371
372
373
374
# File 'lib/active_scaffold/data_structures/column.rb', line 371

def <=>(other)
  order_weight = weight <=> other.weight
  order_weight.nonzero? ? order_weight : name.to_s <=> other.name.to_s
end

#==(other) ⇒ Object

this is so that array.delete and array.include?, etc., will work by column name


292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/active_scaffold/data_structures/column.rb', line 292

def ==(other) #:nodoc:
  # another column
  if other.respond_to?(:name) && other.class == self.class
    name == other.name.to_sym
  elsif other.is_a? Symbol
    name == other
  elsif other.is_a? String
    name.to_s == other # avoid creating new symbols
  else # unknown
    eql? other
  end
end

#associated_number?Boolean

Returns:

  • (Boolean)

239
240
241
# File 'lib/active_scaffold/data_structures/column.rb', line 239

def associated_number?
  @associated_number
end

#autolink?Boolean

set an action_link to nested list or inline form in this column

Returns:

  • (Boolean)

161
162
163
# File 'lib/active_scaffold/data_structures/column.rb', line 161

def autolink?
  @autolink
end

#calculation?Boolean

get whether to run a calculation on this column

Returns:

  • (Boolean)

175
176
177
# File 'lib/active_scaffold/data_structures/column.rb', line 175

def calculation?
  !(@calculate == false || @calculate.nil?)
end

this should not only delete any existing link but also prevent column links from being automatically added by later routines


166
167
168
169
# File 'lib/active_scaffold/data_structures/column.rb', line 166

def clear_link
  @link = nil
  @autolink = false
end

#column_typeObject


414
415
416
# File 'lib/active_scaffold/data_structures/column.rb', line 414

def column_type
  ActiveScaffold::OrmChecks.column_type active_record_class, name
end

#convert_to_native?Boolean

Returns:

  • (Boolean)

376
377
378
# File 'lib/active_scaffold/data_structures/column.rb', line 376

def convert_to_native?
  number? && options[:format] && form_ui != :number
end

#default_for_empty_valueObject


401
402
403
# File 'lib/active_scaffold/data_structures/column.rb', line 401

def default_for_empty_value
  (column.null ? nil : column.default) if column
end

#fieldObject

the table.field name for this column, if applicable


406
407
408
# File 'lib/active_scaffold/data_structures/column.rb', line 406

def field
  @field ||= quoted_field(field_name)
end

#field_nameObject

just the field (not table.field)


366
367
368
369
# File 'lib/active_scaffold/data_structures/column.rb', line 366

def field_name
  return nil if virtual?
  @field_name ||= column ? quoted_field_name(column.name) : association.foreign_key
end

142
143
144
145
146
# File 'lib/active_scaffold/data_structures/column.rb', line 142

def link
  return @link.call(self) if frozen? && @link.is_a?(Proc)
  @link = @link.call(self) if @link.is_a? Proc
  @link
end

#number?Boolean

Returns:

  • (Boolean)

283
284
285
# File 'lib/active_scaffold/data_structures/column.rb', line 283

def number?
  @number
end

#number_to_native(value) ⇒ Object


380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/active_scaffold/data_structures/column.rb', line 380

def number_to_native(value)
  return value if value.blank? || !value.is_a?(String)
  native = '.' # native ruby separator
  format = {:separator => '', :delimiter => ''}.merge! I18n.t('number.format', :default => {})
  specific =
    case options[:format]
    when :currency
      I18n.t('number.currency.format', :default => nil)
    when :size
      I18n.t('number.human.format', :default => nil)
    when :percentage
      I18n.t('number.percentage.format', :default => nil)
    end
  format.merge! specific unless specific.nil?
  if format[:separator].blank? || !value.include?(format[:separator]) && value.include?(native) && (format[:delimiter] != native || value !~ /\.\d{3}$/)
    value
  else
    value.gsub(/[^0-9\-#{format[:separator]}]/, '').gsub(format[:separator], native)
  end
end

#paramsObject

Any extra parameters this particular column uses. This is for create/update purposes.


35
36
37
38
# File 'lib/active_scaffold/data_structures/column.rb', line 35

def params
  return @params || NO_PARAMS if frozen?
  @params ||= NO_PARAMS.dup
end

#required?Boolean

Returns:

  • (Boolean)

69
70
71
# File 'lib/active_scaffold/data_structures/column.rb', line 69

def required?
  @required
end

#search_joinsObject

a collection of associations to do left join when this column is included on search


190
191
192
# File 'lib/active_scaffold/data_structures/column.rb', line 190

def search_joins
  @search_joins || @includes
end

#search_joins=(value) ⇒ Object


194
195
196
197
198
199
200
# File 'lib/active_scaffold/data_structures/column.rb', line 194

def search_joins=(value)
  @search_joins =
    case value
    when Array then value
    else [value] # automatically convert to an array
    end
end

#search_sqlObject


218
219
220
221
# File 'lib/active_scaffold/data_structures/column.rb', line 218

def search_sql
  initialize_search_sql if @search_sql == true
  @search_sql
end

#search_sql=(value) ⇒ Object

describes how to search on a column

search = true           default, uses intelligent search sql
search = "CONCAT(a, b)" define your own sql for searching. this should be the "left-side" of a WHERE condition. the operator and value will be supplied by ActiveScaffold.
search = [:a, :b]       searches in both fields

209
210
211
212
213
214
215
216
# File 'lib/active_scaffold/data_structures/column.rb', line 209

def search_sql=(value)
  @search_sql =
    if value
      value == true || value.is_a?(Proc) ? value : Array(value)
    else
      value
    end
end

#searchable?Boolean

Returns:

  • (Boolean)

223
224
225
# File 'lib/active_scaffold/data_structures/column.rb', line 223

def searchable?
  search_sql.present?
end

associate an action_link with this column


149
150
151
152
153
154
155
156
157
158
# File 'lib/active_scaffold/data_structures/column.rb', line 149

def set_link(action, options = {})
  if action.is_a?(ActiveScaffold::DataStructures::ActionLink) || (action.is_a? Proc)
    @link = action
  else
    options[:label] ||= label
    options[:position] ||= :after unless options.key?(:position)
    options[:type] ||= :member
    @link = ActiveScaffold::DataStructures::ActionLink.new(action, options)
  end
end

#show_blank_record?(associated) ⇒ Boolean

Returns:

  • (Boolean)

250
251
252
253
254
# File 'lib/active_scaffold/data_structures/column.rb', line 250

def show_blank_record?(associated)
  return false unless @show_blank_record
  return false unless association.klass.authorized_for?(:crud_type => :create) && !association.readonly?
  association.collection? || (association.singular? && associated.blank?)
end

#sortObject


100
101
102
103
# File 'lib/active_scaffold/data_structures/column.rb', line 100

def sort
  initialize_sort if @sort == true
  @sort
end

#sort=(value) ⇒ Object

sorting on a column can be configured four ways:

sort = true               default, uses intelligent sorting sql default
sort = false              sometimes sorting doesn't make sense
sort = {:sql => ""}       define your own sql for sorting. this should be result in a sortable value in SQL. ActiveScaffold will handle the ascending/descending.
sort = {:method => ""}    define ruby-side code for sorting. this is SLOW with large recordsets!

91
92
93
94
95
96
97
98
# File 'lib/active_scaffold/data_structures/column.rb', line 91

def sort=(value)
  if value.is_a? Hash
    value.assert_valid_keys(:sql, :method)
    @sort = value
  else
    @sort = value ? true : false # force true or false
  end
end

#sort_by(options) ⇒ Object

a configuration helper for the self.sort property. simply provides a method syntax instead of setter syntax.


110
111
112
# File 'lib/active_scaffold/data_structures/column.rb', line 110

def sort_by(options)
  self.sort = options
end

#sortable?Boolean

Returns:

  • (Boolean)

105
106
107
# File 'lib/active_scaffold/data_structures/column.rb', line 105

def sortable?
  sort != false && !sort.nil?
end

#text?Boolean

Returns:

  • (Boolean)

287
288
289
# File 'lib/active_scaffold/data_structures/column.rb', line 287

def text?
  @text
end

#type_for_attributeObject


410
411
412
# File 'lib/active_scaffold/data_structures/column.rb', line 410

def type_for_attribute
  ActiveScaffold::OrmChecks.type_for_attribute active_record_class, name
end

#virtual?Boolean

an interpreted property. the column is virtual if it isn't from the active record model or any associated models

Returns:

  • (Boolean)

278
279
280
# File 'lib/active_scaffold/data_structures/column.rb', line 278

def virtual?
  column.nil? && association.nil?
end