propel_facets 0.1.4 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 213ffd21289407fbd5ea496541026dc6b74ab15ac40c5e664b46b8c8566554b8
4
- data.tar.gz: 445aa9e0fc962b1ea8e0ae2300d59dc14639fe9b76f27b0f2a80a0bda9c5dce9
3
+ metadata.gz: e5233eaef1c8dc1acd2c631b9117c5b1a13c8deb1997d97a0e5fb294c7c55081
4
+ data.tar.gz: 15905b8628b5f2cb805b91ba4e25b36451a23ece1768216f64b0ae4fe964a96e
5
5
  SHA512:
6
- metadata.gz: 629277208c5fcb8a1c45358d8515619fb45e583557bcc3df5775730bffe0e34ce6e6228344b632a6c0c34d4f77be6c77f3f17c75cc842d7211e7a30243ad959c
7
- data.tar.gz: bab90747419b952deb39e0f170785535e9d292a0e9c054c8764e40d3ba9ba9cda7b88b14f1fb2e8cceffeb7ff669ba322a33abaf32ed26a93171df4cf857938d
6
+ metadata.gz: 57cf3b84754b71e1c18d45ac31690531ec212f49bc2179eda78fc3e791b01f0e6cf7c2dbf38f99e42765c45dfd1a39b071446a461ceb88a206339f2303a7ac82
7
+ data.tar.gz: 461b058e8e4f91e575d83560029b738f873c8dd85744be9c22e1bfd343a8c07b53cf1035229ea0906125c8710c20995c51e4f3c4ed568b408f047e2ca816b6e7
data/CHANGELOG.md CHANGED
@@ -14,7 +14,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
  - Metadata inclusion (pagination, counts, etc.)
15
15
  - Performance logging and optimization tools
16
16
 
17
- ## [0.1.4] - 2025-01-23
17
+ ## [0.2.0] - 2025-09-02
18
+
19
+ ### Added
20
+ - **Enhanced facet pattern consistency** - Standardized JSON facet definitions across all models
21
+ - Support for comprehensive User model facets with authentication fields
22
+ - Improved association handling in facet rendering with proper include directives
23
+ - Consistent field inclusion patterns for better API consistency
24
+
25
+ ### Improved
26
+ - **Compatibility updates** - Enhanced integration with PropelAuthentication 0.2.0 and PropelApi 0.2.0
27
+ - Updated to work with new security-first architecture
28
+ - Maintained full compatibility with enhanced JSON facet definitions
29
+ - Support for `PropelAuthenticationConcern` namespace changes
30
+ - Seamless integration with configurable tenancy requirements
31
+
32
+ ### Fixed
33
+ - **JSON facet rendering** - Enhanced association handling and field inclusion
34
+ - Proper handling of organization associations in User model facets
35
+ - Consistent foreign key and association rendering across all model types
36
+
37
+ ## [0.1.4] - 2025-08-15
18
38
 
19
39
  ### Added
20
40
  - **Clean controller generation by default** - PropelFacets controller templates now generate production-ready code
data/better_nesting.md ADDED
@@ -0,0 +1,166 @@
1
+ # Feature Implementation Guide: Per-Association Facet Specification in json_facet includes
2
+
3
+ ## Current State
4
+ The `json_facet` system currently supports including associations, but all included associations use the same facet determined by the `include_as` parameter:
5
+
6
+ ```ruby
7
+ # Current syntax - all associations use :included facet
8
+ json_facet :details,
9
+ fields: [:id, :name],
10
+ include: [:organization, :user, :comments],
11
+ include_as: :included
12
+ ```
13
+
14
+ ## Desired Feature
15
+ Enable specifying different facets for different associations within a single json_facet definition:
16
+
17
+ ```ruby
18
+ # Proposed syntax - each association can specify its own facet
19
+ json_facet :details,
20
+ fields: [:id, :name],
21
+ include: {
22
+ organization: :short, # Use organization's :short facet
23
+ user: :included, # Use user's :included facet
24
+ comments: :minimal # Use comment's :minimal facet
25
+ }
26
+ ```
27
+
28
+ ## Implementation Approach
29
+
30
+ ### 1. Modify `json_facet` method (line 74-85)
31
+ - Detect when `include` is a Hash vs Array
32
+ - Parse Hash format to extract association → facet mappings
33
+ - Maintain backward compatibility with Array format
34
+
35
+ ### 2. Update `facet_serializable_options` method (line 154-161)
36
+ Current code:
37
+ ```ruby
38
+ include = actual[:include].reduce({}) do |memo, current|
39
+ memo.update(current => { facet: include_as }) # Same facet for all
40
+ end
41
+ ```
42
+
43
+ New logic needed:
44
+ ```ruby
45
+ include = actual[:include].reduce({}) do |memo, current|
46
+ if current.is_a?(Hash)
47
+ # Handle { association: :facet_name } format
48
+ current.each do |assoc, facet|
49
+ memo.update(assoc => { facet: facet })
50
+ end
51
+ else
52
+ # Backward compatibility: use include_as for array format
53
+ memo.update(current => { facet: include_as })
54
+ end
55
+ memo
56
+ end
57
+ ```
58
+
59
+ ### 3. Mixed Syntax Support
60
+ Support combining both syntaxes in one facet:
61
+ ```ruby
62
+ json_facet :details,
63
+ include: [:tags, { organization: :short, user: :minimal }],
64
+ include_as: :included # Default for array items
65
+ ```
66
+
67
+ ### 4. Validation & Error Handling
68
+ - Validate that specified facets exist on target models
69
+ - Provide meaningful error messages for missing facets
70
+ - Handle edge cases (nil facets, invalid association names)
71
+
72
+ ## Example Usage Patterns
73
+
74
+ ### Basic Usage
75
+ ```ruby
76
+ class Product < ApplicationRecord
77
+ json_facet :api_response,
78
+ fields: [:id, :name, :price],
79
+ include: {
80
+ category: :short, # Just id, name
81
+ reviews: :summary, # rating, comment excerpt
82
+ seller: :public # name, avatar, rating
83
+ }
84
+ end
85
+ ```
86
+
87
+ ### Mixed with Array Syntax
88
+ ```ruby
89
+ class BlogPost < ApplicationRecord
90
+ json_facet :feed_item,
91
+ fields: [:id, :title, :excerpt],
92
+ include: [
93
+ :tags, # Use default :included facet
94
+ { author: :author_card } # Use custom :author_card facet
95
+ ],
96
+ include_as: :included # Default for array items
97
+ end
98
+ ```
99
+
100
+ ### Nested Facet Chains
101
+ ```ruby
102
+ class User < ApplicationRecord
103
+ json_facet :profile,
104
+ fields: [:id, :username],
105
+ include: {
106
+ organization: :public, # Organization uses its :public facet
107
+ posts: :feed_summary # Posts use their :feed_summary facet
108
+ }
109
+ end
110
+
111
+ class Organization < ApplicationRecord
112
+ json_facet :public,
113
+ fields: [:id, :name, :logo],
114
+ include: { industry: :basic } # Nested includes work too
115
+ end
116
+ ```
117
+
118
+ ## Backward Compatibility Requirements
119
+ - Existing `include: [:association]` syntax must continue working
120
+ - Current `include_as: :facet` behavior must remain unchanged for array includes
121
+ - No breaking changes to existing APIs
122
+
123
+ ## Test Cases to Implement
124
+
125
+ ### 1. Basic Hash Syntax
126
+ ```ruby
127
+ test "should support hash syntax for per-association facets" do
128
+ # Test that each association uses its specified facet
129
+ end
130
+ ```
131
+
132
+ ### 2. Backward Compatibility
133
+ ```ruby
134
+ test "should maintain array syntax compatibility" do
135
+ # Ensure existing code continues working
136
+ end
137
+ ```
138
+
139
+ ### 3. Mixed Syntax
140
+ ```ruby
141
+ test "should support mixed array and hash syntax" do
142
+ # Test combining both syntaxes in one facet
143
+ end
144
+ ```
145
+
146
+ ### 4. Error Handling
147
+ ```ruby
148
+ test "should handle missing facets gracefully" do
149
+ # Test behavior when specified facet doesn't exist
150
+ end
151
+ ```
152
+
153
+ ### 5. Deep Nesting
154
+ ```ruby
155
+ test "should support nested facet chains" do
156
+ # Test that included objects can have their own includes
157
+ end
158
+ ```
159
+
160
+ ## Implementation Priority
161
+ 1. **Phase 1**: Basic Hash syntax support
162
+ 2. **Phase 2**: Mixed Array/Hash syntax
163
+ 3. **Phase 3**: Advanced validation and error handling
164
+ 4. **Phase 4**: Performance optimization for complex nested includes
165
+
166
+ This feature would provide much more granular control over JSON serialization while maintaining the elegant declarative syntax that makes json_facet powerful.
@@ -10,4 +10,10 @@ class ApplicationRecord < ActiveRecord::Base
10
10
  json_facet :included, base: :reference
11
11
  json_facet :short, base: :included, include_as: :reference
12
12
  json_facet :details, base: :short, include_as: :included
13
+
14
+ # Organization scoping for multi-tenancy
15
+ scope :for_organization, ->(organization_id) {
16
+ return none if organization_id.blank?
17
+ where(organization_id: organization_id)
18
+ }
13
19
  end
data/lib/propel_facets.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module PropelFacets
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propel_facets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Propel Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-15 00:00:00.000000000 Z
11
+ date: 2025-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -43,6 +43,7 @@ files:
43
43
  - LICENSE
44
44
  - README.md
45
45
  - Rakefile
46
+ - better_nesting.md
46
47
  - lib/generators/propel_facets/README.md
47
48
  - lib/generators/propel_facets/USAGE
48
49
  - lib/generators/propel_facets/install_generator.rb