class ActiveScaffold::DataStructures::Column
Constants
- NO_OPTIONS
- NO_PARAMS
Attributes
Whether to enable add_existing for this column
the association from the ActiveRecord
class
what string to use to join records from plural associations
cache key to cache column info
define a calculation for the column. anything that ActiveRecord::Calculations::ClassMethods#calculate accepts will do.
Whether this column set is collapsed by default in contexts where collapsing is supported
the ConnectionAdapter::*Column object from the ActiveRecord
class
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.
the singular association which this column belongs to
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.
supported options:
* for association columns * :select - displays a simple <select> or a collection of checkboxes to (dis)associate records
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?
a collection of associations to pre-load when finding the records on a page
Whether to enable inplace editing for this column. Currently works for text columns, in the List.
:table to refresh list true or :row to refresh row
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
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.
a place to store dev’s column specific options
A placeholder text, to be used inside blank text fields to describe, what should be typed in
whether the field is required or not. used on the form for visually indicating the fact to the user. TODO: move into predicate
a collection of columns to load when eager loading is disabled, if it’s nil all columns will be loaded
What columns load from main table
the table name from the ActiveRecord
class
to modify the default order of columns
Public Instance Methods
# 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
# File lib/active_scaffold/data_structures/column.rb, line 303 def associated_number? @associated_number end
# File lib/active_scaffold/data_structures/column.rb, line 494 def attributes=(opts) opts.each do |setting, value| send "#{setting}=", value end end
set an action_link to nested list or inline form in this column
# File lib/active_scaffold/data_structures/column.rb, line 225 def autolink? @autolink end
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
# File lib/active_scaffold/data_structures/column.rb, line 500 def cast(value) ActiveScaffold::OrmChecks.cast active_record_class, name, value end
this should not only delete any existing link but also prevent column links from being automatically added by later routines
# File lib/active_scaffold/data_structures/column.rb, line 230 def clear_link @link = nil @autolink = false end
# File lib/active_scaffold/data_structures/column.rb, line 486 def column_type ActiveScaffold::OrmChecks.column_type active_record_class, name end
# File lib/active_scaffold/data_structures/column.rb, line 429 def convert_to_native? number? && options[:format] && form_ui != :number end
# 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
# File lib/active_scaffold/data_structures/column.rb, line 490 def default_value ActiveScaffold::OrmChecks.column_type active_record_class, name end
# 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
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
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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 16 def inplace_edit=(value) clear_link if value @inplace_edit = value end
# 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
# File lib/active_scaffold/data_structures/column.rb, line 206 def link return @link.call(self) if frozen? && @link.is_a?(Proc) @link = @link.call(self) if @link.is_a? Proc @link end
# File lib/active_scaffold/data_structures/column.rb, line 163 def list_ui @list_ui || form_ui end
# File lib/active_scaffold/data_structures/column.rb, line 167 def list_ui_options @list_ui ? @list_ui_options : form_ui_options end
# 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
# File lib/active_scaffold/data_structures/column.rb, line 347 def number? @number end
# 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
# File lib/active_scaffold/data_structures/column.rb, line 201 def options return @options || NO_OPTIONS if frozen? @options ||= NO_OPTIONS.dup end
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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 478 def quoted_foreign_type quoted_field(quoted_field_name(association.foreign_type)) end
# 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
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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 282 def search_sql initialize_search_sql if @search_sql == true @search_sql end
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
# File lib/active_scaffold/data_structures/column.rb, line 191 def search_ui @search_ui || @form_ui || (:select if association && !association.polymorphic?) end
# File lib/active_scaffold/data_structures/column.rb, line 195 def search_ui_options @search_ui ? @search_ui_options : form_ui_options end
# File lib/active_scaffold/data_structures/column.rb, line 287 def searchable? search_sql.present? end
associate an action_link with this column
# File lib/active_scaffold/data_structures/column.rb, line 213 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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 177 def show_ui @show_ui || list_ui end
# File lib/active_scaffold/data_structures/column.rb, line 181 def show_ui_options @show_ui ? @show_ui_options : list_ui_options end
# File lib/active_scaffold/data_structures/column.rb, line 130 def sort initialize_sort if @sort == true @sort end
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
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
# File lib/active_scaffold/data_structures/column.rb, line 135 def sortable? sort != false && !sort.nil? end
# File lib/active_scaffold/data_structures/column.rb, line 351 def text? @text end
# 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 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 597 def initialize_sort self.sort = if column && !tableless? {:sql => field} else false end end
# File lib/active_scaffold/data_structures/column.rb, line 593 def quoted_field(name) active_record? ? [_quoted_table_name, name].compact.join('.') : name end
# 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
# 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
# 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
# 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
# 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
# File lib/active_scaffold/data_structures/column.rb, line 550 def validator_required_on(val) val.options[:on] ? Array(val.options[:on]) : true end