propel_facets 0.1.4 → 0.2.1

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: 8764980d8f96e30b33af48655e5f663f462c2a163d414d0dd55122b069454bb8
4
+ data.tar.gz: 8c1169ffe3ffbbe48fff25ef54c26ffe2a2fd81c1c63257bac4eeda9992497d3
5
5
  SHA512:
6
- metadata.gz: 629277208c5fcb8a1c45358d8515619fb45e583557bcc3df5775730bffe0e34ce6e6228344b632a6c0c34d4f77be6c77f3f17c75cc842d7211e7a30243ad959c
7
- data.tar.gz: bab90747419b952deb39e0f170785535e9d292a0e9c054c8764e40d3ba9ba9cda7b88b14f1fb2e8cceffeb7ff669ba322a33abaf32ed26a93171df4cf857938d
6
+ metadata.gz: 8312227990dd32b4026485fd9e331fea3504019342741511214a33754b8e8c67cbe4ce25817fb4f4d319dcf1e4a4e25e305eab590c96a6a8f860d64343021a8c
7
+ data.tar.gz: 4a8184cff3c9bf000f2b42e71cc7d2fb8f6c00c5b7f6c03a9035eba1079d2820cca44e9518dc86000994b4d475b4dc10d2ddefad3c89e715026889cd1d2f8fd4
data/CHANGELOG.md CHANGED
@@ -14,7 +14,37 @@ 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.1] - 2025-01-14
18
+
19
+ ### Fixed
20
+ - **Critical generator bug**: Fixed missing `for_organization` scope in ApplicationRecord installation
21
+ - Install generator now properly adds `for_organization` scope when ApplicationRecord already exists
22
+ - Previously only added ModelFacet includes but not the multi-tenancy scope required by PropelApi controllers
23
+ - Enhanced scope implementation to handle both Organization objects and integer IDs
24
+ - Resolves `NoMethodError: undefined method 'for_organization' for Model:Class` in fresh Rails installations
25
+ - Updated both injection method and template files for consistency
26
+
27
+ ## [0.2.0] - 2025-09-02
28
+
29
+ ### Added
30
+ - **Enhanced facet pattern consistency** - Standardized JSON facet definitions across all models
31
+ - Support for comprehensive User model facets with authentication fields
32
+ - Improved association handling in facet rendering with proper include directives
33
+ - Consistent field inclusion patterns for better API consistency
34
+
35
+ ### Improved
36
+ - **Compatibility updates** - Enhanced integration with PropelAuthentication 0.2.0 and PropelApi 0.2.0
37
+ - Updated to work with new security-first architecture
38
+ - Maintained full compatibility with enhanced JSON facet definitions
39
+ - Support for `PropelAuthenticationConcern` namespace changes
40
+ - Seamless integration with configurable tenancy requirements
41
+
42
+ ### Fixed
43
+ - **JSON facet rendering** - Enhanced association handling and field inclusion
44
+ - Proper handling of organization associations in User model facets
45
+ - Consistent foreign key and association rendering across all model types
46
+
47
+ ## [0.1.4] - 2025-08-15
18
48
 
19
49
  ### Added
20
50
  - **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.
@@ -92,6 +92,18 @@ module PropelFacets
92
92
  json_facet :short, base: :included, include_as: :reference
93
93
  json_facet :details, base: :short, include_as: :included
94
94
 
95
+ # Organization scoping for multi-tenancy
96
+ scope :for_organization, ->(organization_or_id) {
97
+ case organization_or_id
98
+ when nil
99
+ none # No organization = no access
100
+ when Organization
101
+ where(organization: organization_or_id)
102
+ else
103
+ where(organization_id: organization_or_id)
104
+ end
105
+ }
106
+
95
107
  RUBY
96
108
  end
97
109
  end
@@ -10,4 +10,16 @@ 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_or_id) {
16
+ case organization_or_id
17
+ when nil
18
+ none # No organization = no access
19
+ when Organization
20
+ where(organization: organization_or_id)
21
+ else
22
+ where(organization_id: organization_or_id)
23
+ end
24
+ }
13
25
  end
data/lib/propel_facets.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module PropelFacets
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.1"
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.1
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