store_model 4.4.0 → 4.5.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: fe31f43187a97021f54c79cbc8372b7e2b1c5a3c4bcb7b07b13def128bf69f34
4
- data.tar.gz: '0456813d7c47e3a9888c23bd83dc90c233f8919734766e348c064350c3d502ce'
3
+ metadata.gz: b9c6db50613221bc69d952fdaed0cb2f1ae07a8c3730748e1166fb93d9538386
4
+ data.tar.gz: f40dae854bd0900ed4f79096fa721da565c6d472b9b187a367cb03f7b3cd2da8
5
5
  SHA512:
6
- metadata.gz: 54a697b1a4782fa6bf3a6f84972789f6b42aab7ef9702e243d7fa4b9d7a6c035ea1421a560eb848083dd414b9bd594d577ca82a50642718d80607d742db64561
7
- data.tar.gz: d591bf765bb19d91cc7972762349075edbb5ec9d633f3b0e4b9c290069af132e35b9d011e4537de43c18f3de76ca863e8b0576d93502ac95b24e4abb250bedd3
6
+ metadata.gz: 50a646560709d22bbb3a6c828cf7834e84dcc9998e1bebc619fcee0953a4b1962728573e18169444c28ef0fa49fcbfc88c3f3bb0de0a1828293a1397b4f13110
7
+ data.tar.gz: 684aa3e90eb4886709ad0960d1ff5092b6223d3393e9dc72276ef149262e82c549ac2de1727385655598e5c953e2f346a160daf15ce4df4f27e163af3a1a5c08
data/README.md CHANGED
@@ -122,6 +122,48 @@ def supplier_params
122
122
  end
123
123
  ```
124
124
 
125
+ ### ActiveAdmin Integration
126
+
127
+ If you're using [ActiveAdmin](https://activeadmin.info/), enable compatibility mode to make the `has_many` form helper work with StoreModel attributes:
128
+
129
+ ```ruby
130
+ # config/initializers/store_model.rb
131
+ StoreModel.config.active_admin_compatibility = true
132
+ ```
133
+
134
+ Example usage:
135
+
136
+ ```ruby
137
+ # app/models/supplier.rb
138
+ class Supplier
139
+ include StoreModel::Model
140
+
141
+ attribute :title, :string
142
+ attribute :address, :string
143
+ end
144
+
145
+ # app/models/product.rb
146
+ class Product < ApplicationRecord
147
+ include StoreModel::NestedAttributes
148
+
149
+ attribute :suppliers, Supplier.to_array_type
150
+ accepts_nested_attributes_for :suppliers, allow_destroy: true
151
+ end
152
+
153
+ # app/admin/products.rb
154
+ ActiveAdmin.register Product do
155
+ permit_params suppliers_attributes: [:title, :address, :_destroy]
156
+
157
+ form do |f|
158
+ f.has_many :suppliers, allow_destroy: true do |s|
159
+ s.input :title
160
+ s.input :address
161
+ end
162
+ f.actions
163
+ end
164
+ end
165
+ ```
166
+
125
167
  ## Documentation
126
168
 
127
169
  1. [Installation](./docs/installation.md)
@@ -32,11 +32,19 @@ module StoreModel
32
32
  # @return [Boolean]
33
33
  attr_accessor :enable_parent_assignment
34
34
 
35
+ # Controls if ActiveAdmin compatibility patches are applied.
36
+ # When enabled, adds methods like `new_record?` and `reflect_on_association`
37
+ # that are expected by ActiveAdmin's form builders.
38
+ # Default: false
39
+ # @return [Boolean]
40
+ attr_accessor :active_admin_compatibility
41
+
35
42
  def initialize
36
43
  @serialize_unknown_attributes = true
37
44
  @enable_parent_assignment = true
38
45
  @serialize_enums_using_as_json = true
39
46
  @serialize_empty_attributes = true
47
+ @active_admin_compatibility = false
40
48
  end
41
49
  end
42
50
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StoreModel
4
+ # ActiveAdmin compatibility patches
5
+ #
6
+ # This module contains patches that make StoreModel compatible with ActiveAdmin's
7
+ # form builders, particularly the has_many helper which expects certain ActiveRecord-like
8
+ # methods to be present.
9
+ #
10
+ # To enable these patches, set:
11
+ # StoreModel.config.active_admin_compatibility = true
12
+ module ActiveAdminCompatibility
13
+ # Reflection class for StoreModel associations.
14
+ # This provides compatibility with form builders like ActiveAdmin's has_many
15
+ # that expect ActiveRecord-style reflection objects.
16
+ class Reflection
17
+ attr_reader :name, :klass
18
+
19
+ # @param name [Symbol] association name
20
+ # @param klass [Class] the StoreModel class
21
+ def initialize(name, klass)
22
+ @name = name
23
+ @klass = klass
24
+ end
25
+ end
26
+
27
+ # Patch for StoreModel::Model to add new_record? method
28
+ module NewRecordPatch
29
+ # Always returns true for StoreModel instances when ActiveAdmin compatibility is enabled.
30
+ # This is needed for compatibility with form builders like ActiveAdmin's has_many.
31
+ # For ActiveRecord models, delegates to the original implementation.
32
+ #
33
+ # @return [Boolean]
34
+ def new_record?
35
+ super
36
+ rescue NoMethodError
37
+ true
38
+ end
39
+ end
40
+
41
+ # Patch for StoreModel::NestedAttributes::ClassMethods to add reflection methods
42
+ module ReflectionMethods
43
+ # Returns reflection for the given association name.
44
+ # This provides compatibility with form builders like ActiveAdmin's has_many.
45
+ # First checks if the attribute is a StoreModel collection type, and if so,
46
+ # returns a reflection for it. Otherwise, delegates to the original implementation
47
+ # for ActiveRecord associations.
48
+ #
49
+ # @param name [Symbol, String] association name
50
+ # @return [StoreModel::ActiveAdminCompatibility::Reflection, nil]
51
+ def reflect_on_association(name)
52
+ # First check if this is a StoreModel attribute
53
+ # Use attribute_types directly to get the type for the given attribute
54
+ type = attribute_types[name.to_s]
55
+
56
+ if type.is_a?(StoreModel::Types::ManyBase) && type.respond_to?(:model_klass) && type.model_klass
57
+ # Return reflection for StoreModel collection attributes
58
+ return StoreModel::ActiveAdminCompatibility::Reflection.new(name.to_sym, type.model_klass)
59
+ end
60
+
61
+ # Not a StoreModel attribute, try to call the original method for ActiveRecord associations
62
+ super
63
+ rescue NoMethodError
64
+ # No super method exists (pure StoreModel class), return nil
65
+ nil
66
+ end
67
+ end
68
+ end
69
+ end
@@ -15,6 +15,7 @@ module StoreModel
15
15
  base.include ActiveRecord::AttributeMethods::BeforeTypeCast
16
16
  base.include ActiveModel::AttributeMethods
17
17
  base.include StoreModel::NestedAttributes
18
+ base.include ActiveModel::Validations::Callbacks
18
19
 
19
20
  if ActiveModel::VERSION::MAJOR >= 8 && ActiveModel::VERSION::MINOR >= 1
20
21
  base.include ActiveModel::Attributes::Normalization
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "store_model/ext/active_model/attributes"
4
4
  require "store_model/ext/active_record/base"
5
+ require "store_model/ext/active_admin_compatibility"
5
6
 
6
7
  module StoreModel # :nodoc:
7
8
  class Railtie < Rails::Railtie # :nodoc:
@@ -11,6 +12,11 @@ module StoreModel # :nodoc:
11
12
  ActiveModel::Attributes.prepend(Attributes)
12
13
  prepend(Base)
13
14
  end
15
+
16
+ if StoreModel.config.active_admin_compatibility
17
+ StoreModel::Model.prepend(ActiveAdminCompatibility::NewRecordPatch)
18
+ StoreModel::NestedAttributes::ClassMethods.prepend(ActiveAdminCompatibility::ReflectionMethods)
19
+ end
14
20
  end
15
21
  end
16
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StoreModel # :nodoc:
4
- VERSION = "4.4.0"
4
+ VERSION = "4.5.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: store_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
@@ -84,6 +84,7 @@ files:
84
84
  - lib/store_model/combine_errors_strategies/merge_hash_error_strategy.rb
85
85
  - lib/store_model/configuration.rb
86
86
  - lib/store_model/enum.rb
87
+ - lib/store_model/ext/active_admin_compatibility.rb
87
88
  - lib/store_model/ext/active_model/attributes.rb
88
89
  - lib/store_model/ext/active_record/base.rb
89
90
  - lib/store_model/ext/parent_assignment.rb