class ActiveScaffold::DataStructures::Column

Constants

NO_OPTIONS
NO_PARAMS

Attributes

active_record_class[R]
allow_add_existing[RW]

Whether to enable add_existing for this column

associated_limit[RW]
associated_number[W]
association[R]

the association from the ActiveRecord class

association_join_text[RW]

what string to use to join records from plural associations

cache_key[R]

cache key to cache column info

calculate[RW]

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

collapsed[RW]

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

column[R]

the ConnectionAdapter::*Column object from the ActiveRecord class

css_class[RW]

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.

delegated_association[R]

the singular association which this column belongs to

description[W]

a textual description of the column and its contents. this will be displayed with any associated form input widget, so you may want to consider adding a content example.

form_ui[R]

supported options:

* for association columns
  * :select - displays a simple <select> or a collection of checkboxes to (dis)associate records
form_ui_options[R]
hide_form_column_if[RW]

add a custom attr_accessor that can contain a Proc (or boolean or symbol) that will be called when the column renders, such that we can dynamically hide or show the column with an element that can be replaced by update_columns, but won’t affect the form submission. The value can be set in the scaffold controller as follows to dynamically hide the column based on a Proc’s output: config.columns.hide_form_column_if = Proc.new { |record, column, scope| record.vehicle_type == ‘tractor’ } OR to always hide the column: config.columns.hide_form_column_if = true OR to call a method on the record to determine whether to hide the column: config.columns.hide_form_column_if = :hide_tractor_fields?

includes[R]

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

inplace_edit[R]

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

inplace_edit_update[RW]

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

label[W]

the display-name of the column. this will be used, for instance, as the column title in the table and as the field name in the form. if left alone it will utilize human_attribute_name which includes localization

model[R]
name[R]

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.

number[W]
options[W]

a place to store dev’s column specific options

placeholder[W]

A placeholder text, to be used inside blank text fields to describe, what should be typed in

required[W]

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

select_associated_columns[RW]

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

select_columns[RW]

What columns load from main table

send_form_on_update_column[RW]
show_blank_record[W]
table[R]

the table name from the ActiveRecord class

update_columns[R]
weight[RW]

to modify the default order of columns

Public Instance Methods

<=>(other) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 424
def <=>(other)
  order_weight = weight <=> other.weight
  order_weight.nonzero? ? order_weight : name.to_s <=> other.name.to_s
end
associated_number?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 303
def associated_number?
  @associated_number
end
attributes=(opts) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 494
def attributes=(opts)
  opts.each do |setting, value|
    send "#{setting}=", value
  end
end
calculation?() click to toggle source

get whether to run a calculation on this column

# File lib/active_scaffold/data_structures/column.rb, line 239
def calculation?
  !(@calculate == false || @calculate.nil?)
end
cast(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 500
def cast(value)
  ActiveScaffold::OrmChecks.cast active_record_class, name, value
end
column_type() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 486
def column_type
  ActiveScaffold::OrmChecks.column_type active_record_class, name
end
convert_to_native?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 429
def convert_to_native?
  number? && options[:format] && form_ui != :number
end
default_for_empty_value() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 454
def default_for_empty_value
  return nil unless column
  if column.is_a?(ActiveModel::Attribute)
    column.value
  elsif active_record?
    null? ? nil : column.default
  elsif mongoid?
    column.default_val
  end
end
default_value() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 490
def default_value
  ActiveScaffold::OrmChecks.column_type active_record_class, name
end
description(record = nil, scope = nil) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 60
def description(record = nil, scope = nil)
  if @description&.respond_to?(:call)
    @description.call(record, self, scope)
  elsif @description
    @description
  else
    I18n.t name, :scope => [:activerecord, :description, active_record_class.to_s.underscore.to_sym], :default => ''
  end
end
field() click to toggle source

the table.field name for this column, if applicable

# File lib/active_scaffold/data_structures/column.rb, line 474
def field
  @field ||= quoted_field(field_name)
end
field_name() click to toggle source

just the field (not table.field)

# File lib/active_scaffold/data_structures/column.rb, line 419
def field_name
  return nil if virtual?
  @field_name ||= column ? quoted_field_name(column.name) : quoted_field_name(association.foreign_key)
end
form_ui=(value) click to toggle source

value must be a Symbol, or an Array of form_ui and options hash which will be used with form_ui only

# File lib/active_scaffold/data_structures/column.rb, line 152
def form_ui=(value)
  check_valid_action_ui_params(value)
  @form_ui, @form_ui_options = *value
end
includes=(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 245
def includes=(value)
  @includes =
    case value
    when Array then value
    else value ? [value] : value # not convert nil to [nil]
    end
end
inplace_edit=(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 16
def inplace_edit=(value)
  clear_link if value
  @inplace_edit = value
end
label(record = nil, scope = nil) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 43
def label(record = nil, scope = nil)
  if @label.respond_to?(:call)
    if record
      @label.call(record, self, scope)
    else
      # sometimes label is called without a record in context (ie, from table
      # headers).  In this case fall back to the humanized attribute name
      # instead of the Proc
      active_record_class.human_attribute_name(name.to_s)
    end
  else
    as_(@label) || active_record_class.human_attribute_name(name.to_s)
  end
end
list_ui() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 163
def list_ui
  @list_ui || form_ui
end
list_ui=(value) click to toggle source

value must be a Symbol, or an Array of list_ui and options hash which will be used with list_ui only

# File lib/active_scaffold/data_structures/column.rb, line 158
def list_ui=(value)
  check_valid_action_ui_params(value)
  @list_ui, @list_ui_options = *value
end
list_ui_options() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 167
def list_ui_options
  @list_ui ? @list_ui_options : form_ui_options
end
null?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 465
def null?
  if active_record? && !column.is_a?(ActiveModel::Attribute)
    column&.null
  else
    true
  end
end
number?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 347
def number?
  @number
end
number_to_native(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 433
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
options() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 201
def options
  return @options || NO_OPTIONS if frozen?
  @options ||= NO_OPTIONS.dup
end
params() click to toggle source

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

# File lib/active_scaffold/data_structures/column.rb, line 35
def params
  return @params || NO_PARAMS if frozen?
  @params ||= NO_PARAMS.dup
end
placeholder() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 72
def placeholder
  @placeholder || I18n.t(name, :scope => [:activerecord, :placeholder, active_record_class.to_s.underscore.to_sym], :default => '')
end
quoted_foreign_type() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 478
def quoted_foreign_type
  quoted_field(quoted_field_name(association.foreign_type))
end
required?(action = nil) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 82
def required?(action = nil)
  if action && @required
    @required == true || @required.include?(action)
  else
    @required
  end
end
search_joins() click to toggle source

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

# File lib/active_scaffold/data_structures/column.rb, line 254
def search_joins
  @search_joins || @includes
end
search_joins=(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 258
def search_joins=(value)
  @search_joins =
    case value
    when Array then value
    else [value] # automatically convert to an array
    end
end
search_sql() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 282
def search_sql
  initialize_search_sql if @search_sql == true
  @search_sql
end
search_sql=(value) click to toggle source

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
# File lib/active_scaffold/data_structures/column.rb, line 273
def search_sql=(value)
  @search_sql =
    if value
      value == true || value.is_a?(Proc) ? value : Array(value)
    else
      value
    end
end
search_ui() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 191
def search_ui
  @search_ui || @form_ui || (:select if association && !association.polymorphic?)
end
search_ui=(value) click to toggle source

value must be a Symbol, or an Array of search_ui and options hash which will be used with search_ui only

# File lib/active_scaffold/data_structures/column.rb, line 186
def search_ui=(value)
  check_valid_action_ui_params(value)
  @search_ui, @search_ui_options = *value
end
search_ui_options() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 195
def search_ui_options
  @search_ui ? @search_ui_options : form_ui_options
end
searchable?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 287
def searchable?
  search_sql.present?
end
show_blank_record?(associated) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 314
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
show_ui() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 177
def show_ui
  @show_ui || list_ui
end
show_ui=(value) click to toggle source

value must be a Symbol, or an Array of show_ui and options hash which will be used with show_ui only

# File lib/active_scaffold/data_structures/column.rb, line 172
def show_ui=(value)
  check_valid_action_ui_params(value)
  @show_ui, @show_ui_options = *value
end
show_ui_options() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 181
def show_ui_options
  @show_ui ? @show_ui_options : list_ui_options
end
sort() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 130
def sort
  initialize_sort if @sort == true
  @sort
end
sort=(value) click to toggle source

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!
# File lib/active_scaffold/data_structures/column.rb, line 121
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) click to toggle source

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

# File lib/active_scaffold/data_structures/column.rb, line 140
def sort_by(options)
  self.sort = options
end
sortable?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 135
def sortable?
  sort != false && !sort.nil?
end
text?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 351
def text?
  @text
end
type_for_attribute() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 482
def type_for_attribute
  ActiveScaffold::OrmChecks.type_for_attribute active_record_class, name
end
update_columns=(column_names) click to toggle source

update dependent columns after value change in form

update_columns = :name
update_columns = [:name, :age]
# File lib/active_scaffold/data_structures/column.rb, line 95
def update_columns=(column_names)
  @update_columns = Array(column_names)
end
virtual?() click to toggle source

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

# File lib/active_scaffold/data_structures/column.rb, line 342
def virtual?
  column.nil? && association.nil?
end

Protected Instance Methods

check_valid_action_ui_params(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 636
def check_valid_action_ui_params(value)
  return true if valid_action_ui_params?(value)
  raise ArgumentError, 'value must be a Symbol, or an array of Symbol and Hash'
end
column_number?() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 580
def column_number?
  return %i[float decimal integer].include? column_type if active_record?
  return @column.type < Numeric if mongoid?
end
default_select_columns() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 559
def default_select_columns
  if association.nil? && column
    [field]
  elsif association&.polymorphic?
    [field, quoted_field(quoted_field_name(association.foreign_type))]
  elsif association
    if association.belongs_to?
      [field]
    else
      columns = []
      if _columns_hash[count_column = "#{association.name}_count"]
        columns << quoted_field(quoted_field_name(count_column))
      end
      if association.through_reflection&.belongs_to?
        columns << quoted_field(quoted_field_name(association.through_reflection.foreign_key))
      end
      columns
    end
  end
end
estimate_weight() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 620
def estimate_weight
  if association&.singular?
    400
  elsif association&.collection?
    500
  elsif %i[created_at updated_at].include?(name)
    600
  elsif %i[name label title].include?(name)
    100
  elsif required?
    200
  else
    300
  end
end
inclusion_validator_for_checkbox?(val) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 554
def inclusion_validator_for_checkbox?(val)
  @form_ui == :checkbox &&
    [[true, false], [false, true]].include?(val.options[:with] || val.options[:within] || val.options[:in])
end
initialize_search_sql() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 606
def initialize_search_sql
  self.search_sql =
    unless virtual?
      if association.nil?
        field.to_s unless tableless?
      elsif association.allow_join?
        [association.quoted_table_name, association.quoted_primary_key].join('.') unless association.klass < ActiveScaffold::Tableless
      end
    end
end
initialize_sort() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 597
def initialize_sort
  self.sort =
    if column && !tableless?
      {:sql => field}
    else
      false
    end
end
quoted_field(name) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 593
def quoted_field(name)
  active_record? ? [_quoted_table_name, name].compact.join('.') : name
end
quoted_field_name(column_name) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 585
def quoted_field_name(column_name)
  if active_record?
    @active_record_class.connection.quote_column_name(column_name)
  else
    column_name.to_s
  end
end
setup_association_info() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 523
def setup_association_info
  assoc = active_record_class.reflect_on_association(name)
  @association =
    if assoc
      if active_record?
        Association::ActiveRecord.new(assoc)
      elsif mongoid?
        Association::Mongoid.new(assoc)
      end
    elsif defined?(ActiveMongoid) && model < ActiveMongoid::Associations
      assoc = active_record_class.reflect_on_am_association(name)
      Association::ActiveMongoid.new(assoc) if assoc
    end
end
setup_defaults_for_column() click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 506
def setup_defaults_for_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 null? ? :boolean : :checkbox
      when :text then :textarea
      end
  end
end
valid_action_ui_params?(value) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 641
def valid_action_ui_params?(value)
  if value.is_a?(Array)
    value.size <= 2 && value[0].is_a?(Symbol) && (value[1].nil? || value[1].is_a?(Hash))
  else
    value.nil? || value.is_a?(Symbol)
  end
end
validator_force_required?(val) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 538
def validator_force_required?(val)
  return false if val.options[:if] || val.options[:unless]
  case val
  when ActiveModel::Validations::PresenceValidator
    validator_required_on(val)
  when ActiveModel::Validations::InclusionValidator
    if !val.options[:allow_nil] && !val.options[:allow_blank] && !inclusion_validator_for_checkbox?(val)
      validator_required_on(val)
    end
  end
end
validator_required_on(val) click to toggle source
# File lib/active_scaffold/data_structures/column.rb, line 550
def validator_required_on(val)
  val.options[:on] ? Array(val.options[:on]) : true
end