Skip to content

Commit

Permalink
Merge pull request #12 from performant-software/feature/udf6_form_com…
Browse files Browse the repository at this point in the history
…ponents

UDF #6 - Form components
  • Loading branch information
dleadbetter authored Sep 26, 2022
2 parents 8d86a9e + 60c0121 commit 73bbdb3
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 1 deletion.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,36 @@ class AddUserDefinedFieldsToMyModel < ActiveRecord::Migration[7.0]
end
```

### Models
Models that include the `UserDefinedFields::Fieldable` concern will be treated as the models that store the user defined data. The will be available in the dropdown list when configuring user defined fields.

Applications that define user defined fields at the model level should call `resolve_defineable` class method with a lambda function that returns the `defineable` model.

```ruby
class MyModel < ApplicationRecord
include UserDefinedFields::Fieldable

resolve_defineable -> (my_model) { my_model.parent }
end
```

### Serializers
To include the `user_defined_fields` array as a set of nested attributes, include the `UserDefinedFields::DefineableSerializer` in the serializer for whatever model the user defined fields belong to. This is only necessary for fields defined at the model level.

```ruby
class ParentModelSerializer < BaseSerializer
include UserDefinedFields::DefineableSerializer
end
```

To include the `user_defined` hash as an attribute, include the `UserDefinedFields::FieldableSerializer` in the model serializer.

```ruby
class MyModelSerializer < BaseSerializer
include UserDefinedFields::FieldableSerializer
end
```

### Components

User defined fields can be configured one of two ways: At the application level, or at the model level.
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/user_defined_fields/database_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module UserDefinedFields
class DatabaseController < ApplicationController
def data_types
data_types = %w(Boolean Date Number Select String Text)
data_types = %w(Boolean Date Number RichText Select String Text)
render json: { data_types: data_types }, status: :ok
end

Expand Down
44 changes: 44 additions & 0 deletions app/models/concerns/user_defined_fields/fieldable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,52 @@ module UserDefinedFields
module Fieldable
extend ActiveSupport::Concern

class_methods do
def resolve_defineable(lambda = nil)
@resolve_defineable = lambda unless lambda.nil?
@resolve_defineable
end
end

included do
# Resourceable parameters
allow_params :user_defined

# Validations
validate :validate_user_defined_fields

private

def validate_user_defined_fields
defineable = self.class.resolve_defineable&.call(self)

query = UserDefinedField.all

if defineable
query = query.where(
defineable_id: defineable.id,
defineable_type: defineable.class.to_s
)
end

query.each do |field|
# Skip if this field is not required
next unless field.required?

# Parse the user defined field and extract the value
json = JSON.parse(self.user_defined || '{}')
value = json[field.column_name]

# Add an error if the value is "empty"
next unless value.nil? ||
(value.is_a?(String) && value.blank?) ||
(value.is_a?(Array) && value.length === 0) ||
(value.is_a?(Hash) && value.empty?)

message = I18n.t('errors.common.required', name: field.column_name)
self.errors.add(:user_defined, [field.column_name, message])
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module UserDefinedFields
module DefineableSerializer
extend ActiveSupport::Concern

included do
show_attributes user_defined_fields: UserDefinedFieldsSerializer
end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module UserDefinedFields
module FieldableSerializer
extend ActiveSupport::Concern

included do
index_attributes :user_defined
show_attributes :user_defined
end

end
end
35 changes: 35 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Files in the config/locales directory are used for internationalization
# and are automatically loaded by Rails. If you want to use locales other
# than English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
# I18n.t "hello"
#
# In views, this is aliased to just `t`:
#
# <%= t("hello") %>
#
# To use a different locale, set it with `I18n.locale`:
#
# I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# The following keys must be escaped otherwise they will not be retrieved by
# the default I18n backend:
#
# true, false, on, off, yes, no
#
# Instead, surround them with single quotes.
#
# en:
# "true": "foo"
#
# To learn more, please read the Rails Internationalization guide
# available at https://guides.rubyonrails.org/i18n.html.

en:
errors:
common:
required: "%{name} is required"

0 comments on commit 73bbdb3

Please sign in to comment.