easy_talk 1.0.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +97 -17
- data/CHANGELOG.md +66 -0
- data/README.md +316 -210
- data/easy_talk.gemspec +39 -0
- data/lib/easy_talk/builders/composition_builder.rb +12 -1
- data/lib/easy_talk/builders/integer_builder.rb +1 -0
- data/lib/easy_talk/builders/object_builder.rb +9 -23
- data/lib/easy_talk/builders/string_builder.rb +9 -0
- data/lib/easy_talk/configuration.rb +2 -8
- data/lib/easy_talk/errors_helper.rb +1 -0
- data/lib/easy_talk/model.rb +83 -56
- data/lib/easy_talk/property.rb +108 -32
- data/lib/easy_talk/schema_definition.rb +13 -18
- data/lib/easy_talk/types/composer.rb +7 -6
- data/lib/easy_talk/validation_builder.rb +327 -0
- data/lib/easy_talk/version.rb +1 -1
- metadata +28 -140
- data/lib/easy_talk/active_record_schema_builder.rb +0 -295
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_talk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergio Bayona
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03
|
10
|
+
date: 2025-09-03 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activemodel
|
@@ -16,6 +16,9 @@ dependencies:
|
|
16
16
|
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
18
|
version: '7.0'
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '9.0'
|
19
22
|
type: :runtime
|
20
23
|
prerelease: false
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -23,6 +26,9 @@ dependencies:
|
|
23
26
|
- - ">="
|
24
27
|
- !ruby/object:Gem::Version
|
25
28
|
version: '7.0'
|
29
|
+
- - "<"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '9.0'
|
26
32
|
- !ruby/object:Gem::Dependency
|
27
33
|
name: activesupport
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
@@ -30,168 +36,49 @@ dependencies:
|
|
30
36
|
- - ">="
|
31
37
|
- !ruby/object:Gem::Version
|
32
38
|
version: '7.0'
|
33
|
-
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - ">="
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '7.0'
|
40
|
-
- !ruby/object:Gem::Dependency
|
41
|
-
name: sorbet-runtime
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - ">="
|
39
|
+
- - "<"
|
45
40
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0
|
41
|
+
version: '9.0'
|
47
42
|
type: :runtime
|
48
43
|
prerelease: false
|
49
44
|
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0.5'
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: activerecord
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
57
45
|
requirements:
|
58
46
|
- - ">="
|
59
47
|
- !ruby/object:Gem::Version
|
60
48
|
version: '7.0'
|
61
|
-
|
62
|
-
prerelease: false
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - ">="
|
49
|
+
- - "<"
|
66
50
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
51
|
+
version: '9.0'
|
68
52
|
- !ruby/object:Gem::Dependency
|
69
|
-
name:
|
53
|
+
name: js_regex
|
70
54
|
requirement: !ruby/object:Gem::Requirement
|
71
55
|
requirements:
|
72
|
-
- - "
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '3.10'
|
75
|
-
type: :development
|
76
|
-
prerelease: false
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - ">="
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: '3.10'
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: rake
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '13.1'
|
89
|
-
type: :development
|
90
|
-
prerelease: false
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ">="
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '13.1'
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: rspec
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - ">="
|
56
|
+
- - "~>"
|
101
57
|
- !ruby/object:Gem::Version
|
102
58
|
version: '3.0'
|
103
|
-
type: :
|
59
|
+
type: :runtime
|
104
60
|
prerelease: false
|
105
61
|
version_requirements: !ruby/object:Gem::Requirement
|
106
62
|
requirements:
|
107
|
-
- - "
|
63
|
+
- - "~>"
|
108
64
|
- !ruby/object:Gem::Version
|
109
65
|
version: '3.0'
|
110
66
|
- !ruby/object:Gem::Dependency
|
111
|
-
name:
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: '2.0'
|
117
|
-
type: :development
|
118
|
-
prerelease: false
|
119
|
-
version_requirements: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '2.0'
|
124
|
-
- !ruby/object:Gem::Dependency
|
125
|
-
name: rspec-mocks
|
126
|
-
requirement: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '3.13'
|
131
|
-
type: :development
|
132
|
-
prerelease: false
|
133
|
-
version_requirements: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - ">="
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '3.13'
|
138
|
-
- !ruby/object:Gem::Dependency
|
139
|
-
name: rubocop
|
140
|
-
requirement: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - ">="
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: '1.21'
|
145
|
-
type: :development
|
146
|
-
prerelease: false
|
147
|
-
version_requirements: !ruby/object:Gem::Requirement
|
148
|
-
requirements:
|
149
|
-
- - ">="
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
version: '1.21'
|
152
|
-
- !ruby/object:Gem::Dependency
|
153
|
-
name: rubocop-rake
|
154
|
-
requirement: !ruby/object:Gem::Requirement
|
155
|
-
requirements:
|
156
|
-
- - ">="
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
version: '0.6'
|
159
|
-
type: :development
|
160
|
-
prerelease: false
|
161
|
-
version_requirements: !ruby/object:Gem::Requirement
|
162
|
-
requirements:
|
163
|
-
- - ">="
|
164
|
-
- !ruby/object:Gem::Version
|
165
|
-
version: '0.6'
|
166
|
-
- !ruby/object:Gem::Dependency
|
167
|
-
name: rubocop-rspec
|
168
|
-
requirement: !ruby/object:Gem::Requirement
|
169
|
-
requirements:
|
170
|
-
- - ">="
|
171
|
-
- !ruby/object:Gem::Version
|
172
|
-
version: '2.29'
|
173
|
-
type: :development
|
174
|
-
prerelease: false
|
175
|
-
version_requirements: !ruby/object:Gem::Requirement
|
176
|
-
requirements:
|
177
|
-
- - ">="
|
178
|
-
- !ruby/object:Gem::Version
|
179
|
-
version: '2.29'
|
180
|
-
- !ruby/object:Gem::Dependency
|
181
|
-
name: sqlite3
|
67
|
+
name: sorbet-runtime
|
182
68
|
requirement: !ruby/object:Gem::Requirement
|
183
69
|
requirements:
|
184
|
-
- - "
|
70
|
+
- - "~>"
|
185
71
|
- !ruby/object:Gem::Version
|
186
|
-
version: '
|
187
|
-
type: :
|
72
|
+
version: '0.5'
|
73
|
+
type: :runtime
|
188
74
|
prerelease: false
|
189
75
|
version_requirements: !ruby/object:Gem::Requirement
|
190
76
|
requirements:
|
191
|
-
- - "
|
77
|
+
- - "~>"
|
192
78
|
- !ruby/object:Gem::Version
|
193
|
-
version: '
|
194
|
-
description: Generate json-schema from plain Ruby classes
|
79
|
+
version: '0.5'
|
80
|
+
description: Generate json-schema from plain Ruby classes with ActiveModel integration
|
81
|
+
for validations and serialization.
|
195
82
|
email:
|
196
83
|
- bayona.sergio@gmail.com
|
197
84
|
executables: []
|
@@ -211,8 +98,8 @@ files:
|
|
211
98
|
- docs/_posts/2024-05-07-welcome-to-jekyll.markdown
|
212
99
|
- docs/about.markdown
|
213
100
|
- docs/index.markdown
|
101
|
+
- easy_talk.gemspec
|
214
102
|
- lib/easy_talk.rb
|
215
|
-
- lib/easy_talk/active_record_schema_builder.rb
|
216
103
|
- lib/easy_talk/builders/base_builder.rb
|
217
104
|
- lib/easy_talk/builders/boolean_builder.rb
|
218
105
|
- lib/easy_talk/builders/collection_helpers.rb
|
@@ -236,6 +123,7 @@ files:
|
|
236
123
|
- lib/easy_talk/tools/function_builder.rb
|
237
124
|
- lib/easy_talk/types/base_composer.rb
|
238
125
|
- lib/easy_talk/types/composer.rb
|
126
|
+
- lib/easy_talk/validation_builder.rb
|
239
127
|
- lib/easy_talk/version.rb
|
240
128
|
homepage: https://github.com/sergiobayona/easy_talk
|
241
129
|
licenses:
|
@@ -243,8 +131,8 @@ licenses:
|
|
243
131
|
metadata:
|
244
132
|
allowed_push_host: https://rubygems.org
|
245
133
|
homepage_uri: https://github.com/sergiobayona/easy_talk
|
246
|
-
source_code_uri: https://github.com/sergiobayona/easy_talk
|
247
134
|
changelog_uri: https://github.com/sergiobayona/easy_talk/blob/main/CHANGELOG.md
|
135
|
+
rubygems_mfa_required: 'true'
|
248
136
|
rdoc_options: []
|
249
137
|
require_paths:
|
250
138
|
- lib
|
@@ -261,5 +149,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
261
149
|
requirements: []
|
262
150
|
rubygems_version: 3.6.2
|
263
151
|
specification_version: 4
|
264
|
-
summary: Generate json-schema from Ruby classes.
|
152
|
+
summary: Generate json-schema from Ruby classes with ActiveModel integration.
|
265
153
|
test_files: []
|
@@ -1,295 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EasyTalk
|
4
|
-
# This class is responsible for building a SchemaDefinition from an ActiveRecord model
|
5
|
-
# It analyzes the database schema and creates a SchemaDefinition that can be
|
6
|
-
# passed to ObjectBuilder for final schema generation
|
7
|
-
class ActiveRecordSchemaBuilder
|
8
|
-
# Mapping of ActiveRecord column types to Ruby classes
|
9
|
-
COLUMN_TYPE_MAP = {
|
10
|
-
string: String,
|
11
|
-
text: String,
|
12
|
-
integer: Integer,
|
13
|
-
bigint: Integer,
|
14
|
-
float: Float,
|
15
|
-
decimal: Float,
|
16
|
-
boolean: T::Boolean,
|
17
|
-
date: Date,
|
18
|
-
datetime: DateTime,
|
19
|
-
timestamp: DateTime,
|
20
|
-
time: Time,
|
21
|
-
json: Hash,
|
22
|
-
jsonb: Hash
|
23
|
-
}.freeze
|
24
|
-
|
25
|
-
# Mapping for format constraints based on column type
|
26
|
-
FORMAT_MAP = {
|
27
|
-
date: 'date',
|
28
|
-
datetime: 'date-time',
|
29
|
-
timestamp: 'date-time',
|
30
|
-
time: 'time'
|
31
|
-
}.freeze
|
32
|
-
|
33
|
-
attr_reader :model
|
34
|
-
|
35
|
-
# Initialize the builder with an ActiveRecord model
|
36
|
-
#
|
37
|
-
# @param model [Class] An ActiveRecord model class
|
38
|
-
# @raise [ArgumentError] If the provided class is not an ActiveRecord model
|
39
|
-
def initialize(model)
|
40
|
-
raise ArgumentError, 'Class must be an ActiveRecord model' unless model.ancestors.include?(ActiveRecord::Base)
|
41
|
-
|
42
|
-
@model = model
|
43
|
-
end
|
44
|
-
|
45
|
-
# Build a SchemaDefinition object from the ActiveRecord model
|
46
|
-
#
|
47
|
-
# @return [EasyTalk::SchemaDefinition] A schema definition built from the database structure
|
48
|
-
def build_schema_definition
|
49
|
-
schema_def = SchemaDefinition.new(model.name)
|
50
|
-
|
51
|
-
# Apply basic schema metadata
|
52
|
-
apply_schema_metadata(schema_def)
|
53
|
-
|
54
|
-
# Add all database columns as properties
|
55
|
-
add_column_properties(schema_def)
|
56
|
-
|
57
|
-
# Add model associations as properties
|
58
|
-
add_association_properties(schema_def) unless EasyTalk.configuration.exclude_associations
|
59
|
-
|
60
|
-
# Add virtual properties defined in schema_enhancements
|
61
|
-
add_virtual_properties(schema_def)
|
62
|
-
|
63
|
-
schema_def
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
# Set top-level schema metadata like title, description, and additionalProperties
|
69
|
-
#
|
70
|
-
# @param schema_def [EasyTalk::SchemaDefinition] The schema definition to modify
|
71
|
-
def apply_schema_metadata(schema_def)
|
72
|
-
# Set title (from enhancements or derive from model name)
|
73
|
-
title = schema_enhancements['title'] || model.name.demodulize.humanize
|
74
|
-
schema_def.title(title)
|
75
|
-
|
76
|
-
# Set description if provided
|
77
|
-
if (description = schema_enhancements['description'])
|
78
|
-
schema_def.description(description)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Set additionalProperties (from enhancements or configuration default)
|
82
|
-
additional_props = if schema_enhancements.key?('additionalProperties')
|
83
|
-
schema_enhancements['additionalProperties']
|
84
|
-
else
|
85
|
-
EasyTalk.configuration.default_additional_properties
|
86
|
-
end
|
87
|
-
schema_def.additional_properties(additional_props)
|
88
|
-
end
|
89
|
-
|
90
|
-
# Add properties based on database columns
|
91
|
-
#
|
92
|
-
# @param schema_def [EasyTalk::SchemaDefinition] The schema definition to modify
|
93
|
-
def add_column_properties(schema_def)
|
94
|
-
filtered_columns.each do |column|
|
95
|
-
# Get column enhancement info if it exists
|
96
|
-
column_enhancements = schema_enhancements.dig('properties', column.name.to_s) || {}
|
97
|
-
|
98
|
-
# Map the database type to Ruby type
|
99
|
-
ruby_type = COLUMN_TYPE_MAP.fetch(column.type, String)
|
100
|
-
|
101
|
-
# If the column is nullable, wrap the type in a Union with NilClass
|
102
|
-
ruby_type = T::Types::Union.new([ruby_type, NilClass]) if column.null
|
103
|
-
|
104
|
-
# Build constraints hash for this column
|
105
|
-
constraints = build_column_constraints(column, column_enhancements)
|
106
|
-
|
107
|
-
# Add the property to schema definition
|
108
|
-
schema_def.property(column.name.to_sym, ruby_type, constraints)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Build constraints hash for a database column
|
113
|
-
#
|
114
|
-
# @param column [ActiveRecord::ConnectionAdapters::Column] The database column
|
115
|
-
# @param enhancements [Hash] Any schema enhancements for this column
|
116
|
-
# @return [Hash] The constraints hash
|
117
|
-
def build_column_constraints(column, enhancements)
|
118
|
-
constraints = {
|
119
|
-
optional: enhancements['optional'],
|
120
|
-
description: enhancements['description'],
|
121
|
-
title: enhancements['title']
|
122
|
-
}
|
123
|
-
|
124
|
-
# Add format constraint for date/time columns
|
125
|
-
if (format = FORMAT_MAP[column.type])
|
126
|
-
constraints[:format] = format
|
127
|
-
end
|
128
|
-
|
129
|
-
# Add max_length for string columns with limits
|
130
|
-
constraints[:max_length] = column.limit if column.type == :string && column.limit
|
131
|
-
|
132
|
-
# Add precision/scale for numeric columns
|
133
|
-
if column.type == :decimal && column.precision
|
134
|
-
constraints[:precision] = column.precision
|
135
|
-
constraints[:scale] = column.scale if column.scale
|
136
|
-
end
|
137
|
-
|
138
|
-
# Add default value if present and not a proc
|
139
|
-
constraints[:default] = column.default if column.default && !column.default.is_a?(Proc)
|
140
|
-
|
141
|
-
# Remove nil values
|
142
|
-
constraints.compact
|
143
|
-
end
|
144
|
-
|
145
|
-
# Add properties based on ActiveRecord associations
|
146
|
-
#
|
147
|
-
# @param schema_def [EasyTalk::SchemaDefinition] The schema definition to modify
|
148
|
-
def add_association_properties(schema_def)
|
149
|
-
model.reflect_on_all_associations.each do |association|
|
150
|
-
# Skip if we can't determine the class or it's in the association exclusion list
|
151
|
-
next if association_excluded?(association)
|
152
|
-
|
153
|
-
# Get association enhancement info if it exists
|
154
|
-
assoc_enhancements = schema_enhancements.dig('properties', association.name.to_s) || {}
|
155
|
-
|
156
|
-
case association.macro
|
157
|
-
when :belongs_to, :has_one
|
158
|
-
schema_def.property(
|
159
|
-
association.name,
|
160
|
-
association.klass,
|
161
|
-
{ optional: assoc_enhancements['optional'], description: assoc_enhancements['description'] }.compact
|
162
|
-
)
|
163
|
-
when :has_many, :has_and_belongs_to_many
|
164
|
-
schema_def.property(
|
165
|
-
association.name,
|
166
|
-
T::Array[association.klass],
|
167
|
-
{ optional: assoc_enhancements['optional'], description: assoc_enhancements['description'] }.compact
|
168
|
-
)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# Add virtual properties defined in schema_enhancements
|
174
|
-
#
|
175
|
-
# @param schema_def [EasyTalk::SchemaDefinition] The schema definition to modify
|
176
|
-
def add_virtual_properties(schema_def)
|
177
|
-
return unless schema_enhancements['properties']
|
178
|
-
|
179
|
-
schema_enhancements['properties'].each do |name, options|
|
180
|
-
next unless options['virtual']
|
181
|
-
|
182
|
-
# Map string type name to Ruby class
|
183
|
-
ruby_type = map_type_string_to_ruby_class(options['type'] || 'string')
|
184
|
-
|
185
|
-
# Build constraints for virtual property
|
186
|
-
constraints = {
|
187
|
-
description: options['description'],
|
188
|
-
title: options['title'],
|
189
|
-
optional: options['optional'],
|
190
|
-
format: options['format'],
|
191
|
-
default: options['default'],
|
192
|
-
min_length: options['minLength'],
|
193
|
-
max_length: options['maxLength'],
|
194
|
-
enum: options['enum']
|
195
|
-
}.compact
|
196
|
-
|
197
|
-
# Add the virtual property
|
198
|
-
schema_def.property(name.to_sym, ruby_type, constraints)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
# Map a type string to a Ruby class
|
203
|
-
#
|
204
|
-
# @param type_str [String] The type string (e.g., 'string', 'integer')
|
205
|
-
# @return [Class] The corresponding Ruby class
|
206
|
-
def map_type_string_to_ruby_class(type_str)
|
207
|
-
case type_str.to_s.downcase
|
208
|
-
when 'string' then String
|
209
|
-
when 'integer' then Integer
|
210
|
-
when 'number' then Float
|
211
|
-
when 'boolean' then T::Boolean
|
212
|
-
when 'object' then Hash
|
213
|
-
when 'array' then Array
|
214
|
-
when 'date' then Date
|
215
|
-
when 'datetime' then DateTime
|
216
|
-
when 'time' then Time
|
217
|
-
else String # Default fallback
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
# Get all columns that should be included in the schema
|
222
|
-
#
|
223
|
-
# @return [Array<ActiveRecord::ConnectionAdapters::Column>] Filtered columns
|
224
|
-
def filtered_columns
|
225
|
-
model.columns.reject do |column|
|
226
|
-
config = EasyTalk.configuration
|
227
|
-
excluded_columns.include?(column.name.to_sym) ||
|
228
|
-
(config.exclude_primary_key && column.name == model.primary_key) ||
|
229
|
-
(config.exclude_timestamps && timestamp_column?(column.name)) ||
|
230
|
-
(config.exclude_foreign_keys && foreign_key_column?(column.name))
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
# Check if a column is a timestamp column
|
235
|
-
#
|
236
|
-
# @param column_name [String] The column name
|
237
|
-
# @return [Boolean] True if the column is a timestamp column
|
238
|
-
def timestamp_column?(column_name)
|
239
|
-
%w[created_at updated_at].include?(column_name)
|
240
|
-
end
|
241
|
-
|
242
|
-
# Check if a column is a foreign key column
|
243
|
-
#
|
244
|
-
# @param column_name [String] The column name
|
245
|
-
# @return [Boolean] True if the column is a foreign key column
|
246
|
-
def foreign_key_column?(column_name)
|
247
|
-
column_name.end_with?('_id')
|
248
|
-
end
|
249
|
-
|
250
|
-
# Check if an association should be excluded
|
251
|
-
#
|
252
|
-
# @param association [ActiveRecord::Reflection::AssociationReflection] The association
|
253
|
-
# @return [Boolean] True if the association should be excluded
|
254
|
-
def association_excluded?(association)
|
255
|
-
!association.klass ||
|
256
|
-
excluded_associations.include?(association.name.to_sym) ||
|
257
|
-
association.options[:polymorphic] # Skip polymorphic associations (complex to model)
|
258
|
-
end
|
259
|
-
|
260
|
-
# Get schema enhancements
|
261
|
-
#
|
262
|
-
# @return [Hash] Schema enhancements
|
263
|
-
def schema_enhancements
|
264
|
-
@schema_enhancements ||= if model.respond_to?(:schema_enhancements)
|
265
|
-
model.schema_enhancements.deep_transform_keys(&:to_s)
|
266
|
-
else
|
267
|
-
{}
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
# Get all excluded columns
|
272
|
-
#
|
273
|
-
# @return [Array<Symbol>] Excluded column names
|
274
|
-
def excluded_columns
|
275
|
-
@excluded_columns ||= begin
|
276
|
-
config = EasyTalk.configuration
|
277
|
-
global_exclusions = config.excluded_columns || []
|
278
|
-
model_exclusions = schema_enhancements['ignore'] || []
|
279
|
-
|
280
|
-
# Combine and convert to symbols for consistent comparison
|
281
|
-
(global_exclusions + model_exclusions).map(&:to_sym)
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
# Get all excluded associations
|
286
|
-
#
|
287
|
-
# @return [Array<Symbol>] Excluded association names
|
288
|
-
def excluded_associations
|
289
|
-
@excluded_associations ||= begin
|
290
|
-
model_exclusions = schema_enhancements['ignore_associations'] || []
|
291
|
-
model_exclusions.map(&:to_sym)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|