Class: CustomField
- Defined in:
- app/models/fields/custom_field.rb
Overview
Implementation Notes
Adding database columns dynamically is not usually recommended, and can be potentially unsafe. However, the only alternative would be static migrations, and we want to let users add custom fields without having to restart their server. We could not use the EAV model for performance reasons, since we need to retain the ability to filter and search across thousands of records with potentially hundreds of custom fields.
We have solved all of the major issues:
-
Custom fields for view templates are dynamically generated based on normalized database records in the ‘fields’ table, instead of ActiveRecord’s cached attributes.
-
Concurrency issues are resolved by using ‘method_missing’ to refresh a model’s column information when fields are added by a separate server process.
-
The custom field can be renamed or deleted, but database columns are never renamed or destroyed. A rake task can be run to purge any orphaned columns.
-
Custom field types can only be changed if the database can support the transition. For example, you can change an ‘email’ field to a ‘string’, but not to a ‘datetime’, since changing the type of the database column would cause data to be lost.
Constant Summary collapse
- SAFE_DB_TRANSITIONS =
{ :any => [[:date, :time, :timestamp], [:integer, :float]], :one => {:string => :text} }
Constants inherited from Field
Field::FIELD_TYPES, Field::KLASSES
Instance Method Summary collapse
Methods inherited from Field
#collection_string, #collection_string=, #column_type, field_types, #input_options, #render, #render_value
Instance Method Details
#available_as ⇒ Object
70 71 72 73 74 |
# File 'app/models/fields/custom_field.rb', line 70 def available_as Field.field_types.reject do |new_type, params| db_transition_safety(as, new_type) == :unsafe end end |