Model fields
Compony fields are your models' attributes that you wish to expose in your application's UI. They are a central place to store important information about those attributes, accessible from everywhere and without the need for a database connection.
Every Compony field must define at least a name and type. Compony types and ActiveRecord types are similar but not equivalent. While ActiveRecord uses types for storing data in the DB, Compony fields use them for presenting it. For instance, the Compony "string" type covers any kind of string, including ActiveRecord's "string", "text" etc. Similarly, Compony has no "numeric" type - use "integer" or "decimal" instead, depending on whether or not you want to show decimals or not. There are additional field types like "color", "url" etc. You can find a complete list of all Compony field types in the module Compony::ModelFields.
Compony fields support Postgres arrays (non-nested).
A particularly interesting model field is Association which handles belongs_to, has_many and has_one associations, automatically resolving the association's nature and providing links to the appropriate component.
Every Compony field can further take an arbitrary amount of additional named arguments. Those can be retrieved by calling YourRailsModel.fields[:field_name].extra_attrs.
Here is an example call to fields for a User model:
# app/models/user.rb
class User < ApplicationRecord
field :first_name, :string
field :last_name, :string
field :user_role, :anchormodel
field :website, :url
field :created_at, :datetime
field :updated_at, :datetime
end
All fields declared this way are automatically exported as Rails Model attributes. Note that this also means that you should never declare password and password_confirmation as a Compony field, as you will get the ArgumentError "One or more password arguments are required" otherwise. Read more about handling password fields in the section about Compony::Components::Form.
Compony fields provide the following features:
- a label that lets you generate a name for the column:
User.fields[:first_name].label value_for: given a model instance, formats the data (e.g. a field of type "url" will produce a link).- Features for forms:
simpleform_inputauto-generates in input for a simple form (from thesimple_formgem).simpleform_input_hiddenauto-generates a hidden input.schema_lineauto-generates a DSL call for Schemacop v3 (from theschemacopgem), which is useful for parameter validation.
You can then use these fields in other components, for instance a list as described in the example at the top of this guide:
User.fields.values.each do |field|
span do
concat "#{field.label}: #{field.value_for(user)} " # Display the field's label and apply it to value
end
end
Implementing your own fields
You can implement your own model fields. Make sure they are all within the same namespace and inherit at least from Compony::ModelFields::Base. To enable them, write an initializer that overwrites the array Compony.model_field_namespaces. Namespaces listed in the array are prioritized from first to last. If a field (e.g. String) exists in multiple declared namespaces, the first will be used. This allows you to overwrite Compony fields.
Example:
# config/initializers/compony.rb
Compony.model_field_namespaces = ['MyCustomModelFields', 'Compony::ModelFields']
You can then implement MyCustomModelFields::Animal, MyCustomModelFields::String etc. You can then use field :fav_animal, :animal in your model.