Skip to content

Commit

Permalink
Merge pull request #10 from performant-software/feature/udf9_user_def…
Browse files Browse the repository at this point in the history
…ined_fields

UDF #9 - User Defined Fields
  • Loading branch information
dleadbetter authored Sep 26, 2022
2 parents ac0d054 + f149cff commit b7d6335
Show file tree
Hide file tree
Showing 19 changed files with 318 additions and 15 deletions.
13 changes: 6 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
source "https://rubygems.org"
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Specify your gem's dependencies in user_defined_fields.gemspec.
gemspec
gem 'resource_api', git: 'https://github.com/performant-software/resource-api.git', tag: 'v0.4.2'

gem "sqlite3"
gem 'sqlite3'

gem "sprockets-rails"
gem 'sprockets-rails'

# Start debugger with binding.b [https://github.com/ruby/debug]
# gem "debug", ">= 1.0.0"
# Specify your gem's dependencies in user_defined_fields.gemspec.
gemspec
181 changes: 181 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
GIT
remote: https://github.com/performant-software/resource-api.git
revision: f1de1653b67fc1d623d7418e92d3bb3134df800e
tag: v0.4.2
specs:
resource_api (0.1.0)
pagy (~> 5.10)
rails (>= 6.0.3.2, < 8)

PATH
remote: .
specs:
user_defined_fields (0.1.0)
rails (>= 6.0.3.2, < 8)
resource_api

GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.3.1)
actionpack (= 7.0.3.1)
activejob (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.3.1)
actionpack (= 7.0.3.1)
actionview (= 7.0.3.1)
activejob (= 7.0.3.1)
activesupport (= 7.0.3.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.3.1)
actionview (= 7.0.3.1)
activesupport (= 7.0.3.1)
rack (~> 2.0, >= 2.2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.3.1)
actionpack (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.3.1)
activesupport (= 7.0.3.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.3.1)
activesupport (= 7.0.3.1)
globalid (>= 0.3.6)
activemodel (7.0.3.1)
activesupport (= 7.0.3.1)
activerecord (7.0.3.1)
activemodel (= 7.0.3.1)
activesupport (= 7.0.3.1)
activestorage (7.0.3.1)
actionpack (= 7.0.3.1)
activejob (= 7.0.3.1)
activerecord (= 7.0.3.1)
activesupport (= 7.0.3.1)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
builder (3.2.4)
concurrent-ruby (1.1.10)
crass (1.0.6)
digest (3.1.0)
erubi (1.10.0)
globalid (1.0.0)
activesupport (>= 5.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
loofah (2.18.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
minitest (5.16.2)
net-imap (0.2.3)
digest
net-protocol
strscan
net-pop (0.1.1)
digest
net-protocol
timeout
net-protocol (0.1.3)
timeout
net-smtp (0.3.1)
digest
net-protocol
timeout
nio4r (2.5.8)
nokogiri (1.13.8-x86_64-darwin)
racc (~> 1.4)
pagy (5.10.1)
activesupport
racc (1.6.0)
rack (2.2.4)
rack-test (2.0.2)
rack (>= 1.3)
rails (7.0.3.1)
actioncable (= 7.0.3.1)
actionmailbox (= 7.0.3.1)
actionmailer (= 7.0.3.1)
actionpack (= 7.0.3.1)
actiontext (= 7.0.3.1)
actionview (= 7.0.3.1)
activejob (= 7.0.3.1)
activemodel (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
bundler (>= 1.15.0)
railties (= 7.0.3.1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
railties (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rake (13.0.6)
sprockets (4.0.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sqlite3 (1.4.2)
strscan (3.0.4)
thor (1.2.1)
timeout (0.3.0)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.6.0)

PLATFORMS
x86_64-darwin-19

DEPENDENCIES
resource_api!
sprockets-rails
sqlite3
user_defined_fields!

BUNDLED WITH
2.3.16
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@ $ gem install user_defined_fields
## Usage

#### Migrations
To install the database table necessary to support user defined fields, use the following command:

```bash
bundle exec rails user_defined_fields:install:migrations
```

To install the `user_defined` column on a model, use the following command:

```bash
bundle exec rails generate user_defined_fields:install my_model
bundle exec rails generate user_defined_fields:add my_model
```

This will generate the following migration:

```ruby
class InstallUserDefinedFieldsOnMyModel < ActiveRecord::Migration[7.0]
class AddUserDefinedFieldsToMyModel < ActiveRecord::Migration[7.0]
def up
add_column :my_model, :user_defined, :jsonb, default: {}
add_index :my_model, :user_defined, using: :gin
Expand Down
15 changes: 14 additions & 1 deletion app/controllers/user_defined_fields/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
module UserDefinedFields
class ApplicationController < ActionController::API
class ApplicationController < UserDefinedFields.config.base_controller_class.constantize
def current_user
return super if defined?(super)

nil
end

def item_class
"UserDefinedFields::#{controller_name.singularize.classify}".constantize
end

def serializer_class
"UserDefinedFields::#{"#{controller_name}_serializer".classify}".constantize
end
end
end
21 changes: 21 additions & 0 deletions app/controllers/user_defined_fields/database_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module UserDefinedFields
class DatabaseController < ApplicationController
def data_types
data_types = %w(Boolean Date Number Select String Text)
render json: { data_types: data_types }, status: :ok
end

def tables
tables = []

ActiveRecord::Base.connection.tables.map do |model|
klass = model.classify
next unless klass.safe_constantize&.included_modules&.include?(Fieldable)

tables << klass.to_s
end

render json: { tables: tables }, status: :ok
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module UserDefinedFields
class UserDefinedFieldsController < ApplicationController
search_attributes :table_name, :column_name
end
end
16 changes: 16 additions & 0 deletions app/models/concerns/user_defined_fields/defineable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module UserDefinedFields
module Defineable
extend ActiveSupport::Concern

included do
# Relationships
has_many :user_defined_fields, as: :defineable, dependent: :destroy, class_name: 'UserDefinedFields::UserDefinedField'

# Nested attributes
accepts_nested_attributes_for :user_defined_fields, allow_destroy: true

# Resourceable parameters
allow_params user_defined_fields_attributes: [:id, :_destroy, *UserDefinedField.permitted_params]
end
end
end
9 changes: 9 additions & 0 deletions app/models/concerns/user_defined_fields/fieldable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module UserDefinedFields
module Fieldable
extend ActiveSupport::Concern

included do
allow_params :user_defined
end
end
end
3 changes: 3 additions & 0 deletions app/models/user_defined_fields/application_record.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module UserDefinedFields
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true

# Includes
include Resourceable
end
end
9 changes: 9 additions & 0 deletions app/models/user_defined_fields/user_defined_field.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module UserDefinedFields
class UserDefinedField < ApplicationRecord
# Relationships
belongs_to :defineable, polymorphic: true, optional: true

# Resourceable parameters
allow_params :table_name, :column_name, :data_type, :required, :allow_multiple, options: []
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module UserDefinedFields
class UserDefinedFieldsSerializer < BaseSerializer
index_attributes :id, :table_name, :column_name, :data_type, :required, :allow_multiple, :options
show_attributes :id, :table_name, :column_name, :data_type, :required, :allow_multiple, :options
end
end
1 change: 0 additions & 1 deletion bin/rails
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

ENGINE_ROOT = File.expand_path("..", __dir__)
ENGINE_PATH = File.expand_path("../lib/user_defined_fields/engine", __dir__)
APP_PATH = File.expand_path("../test/dummy/config/application", __dir__)

# Set up gems listed in the Gemfile.
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
Expand Down
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
UserDefinedFields::Engine.routes.draw do
get :data_types, controller: :database, action: :data_types
get :tables, controller: :database, action: :tables

resources :user_defined_fields
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class CreateUserDefinedFieldsUserDefinedFields < ActiveRecord::Migration[6.0]
def up
create_table :user_defined_fields_user_defined_fields do |t|
t.references :defineable, polymorphic: true, null: true, index: { name: 'index_user_defined_fields_on_defineable' }
t.string :table_name
t.string :column_name
t.string :data_type
t.boolean :required
t.boolean :allow_multiple
t.text :options, array: true, default: []

t.timestamps
end
end

def down
drop_table :user_defined_fields_user_defined_fields
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module UserDefinedFields
module Generators
class InstallGenerator < Rails::Generators::Base
class AddGenerator < Rails::Generators::Base
# Includes
include ActiveRecord::Generators::Migration

Expand All @@ -14,8 +14,8 @@ class InstallGenerator < Rails::Generators::Base

def copy_migration
migration_template(
'install.rb',
"db/migrate/install_user_defined_fields_on_#{model_name}.rb",
'add.rb',
"db/migrate/add_user_defined_fields_to_#{model_name}.rb",
migration_version: migration_version,
model_name: model_name
)
Expand Down
7 changes: 6 additions & 1 deletion lib/user_defined_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
require "user_defined_fields/engine"

module UserDefinedFields
# Your code goes here...
mattr_accessor :config, default: Configuration.new

def self.configure(&block)
block.call self.config
end
end

Loading

0 comments on commit b7d6335

Please sign in to comment.