store_model 4.0.0 → 4.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: e3a1d792e0b67515ef121219d4568ef05a2589cb7bf1df33ac36af0f5e0b0efb
4
- data.tar.gz: 98f11df54c5f5b6cd9d4604e889faf95e7b3f3dd85e97c37fe707c112565fc72
3
+ metadata.gz: 1f9b00e47a784173dd8230027f0b6d35cfbc1d1354887a427f565fa9b81b6618
4
+ data.tar.gz: 5d1fa098e8d4e794505059580ae83ebbd08be82239a558e4a48943e4b766ea27
5
5
  SHA512:
6
- metadata.gz: 01a49de46f09b2bff6e25f760b2067e4984cf32851feea67bab4c95ff25bd1dd64f31346e286df2f532bbc6f4d37f9d6d8a3a16be1cacde32f64ccbc24fdc2bd
7
- data.tar.gz: 73b1a450ba0f2eaca9f66c0761d30725af3403fa425bd8b7dca15b5d4d7c794948c9671ab6d6c78304a547db6401ba6388db0f703750483c47bc530995c6c1d5
6
+ metadata.gz: 39d21ccbcb990453a56557ea0d839ee8a8f49f4030d6e5e5cca2d6a4cee62d27624f74481ddc05b022360eab3d442a3354af9e2f3235d345aef309a4c965c162
7
+ data.tar.gz: 7dbc9b7ba2ee37d5b800cf99a3a2d4c1858ec84e0aec5e0e87d0a35e1ac949817b6fba7d4bf317e7d07f5da3c95178dc30c381aee84e39ffa5ed7c7a796d3529
data/README.md CHANGED
@@ -111,7 +111,7 @@ Resulting in:
111
111
  In the controller:
112
112
  ```ruby
113
113
  def create
114
- @supplier = Supplier.new(supplier_params)
114
+ @supplier = Supplier.from_value(supplier_params)
115
115
  @supplier.save
116
116
  end
117
117
 
@@ -126,6 +126,7 @@ end
126
126
 
127
127
  1. [Installation](./docs/installation.md)
128
128
  2. StoreModel::Model API:
129
+ * [Instantiation](./docs/instantiation.md)
129
130
  * [Validations](./docs/validations.md)
130
131
  * [Enums](./docs/enums.md)
131
132
  * [Nested models](./docs/nested_models.md)
@@ -19,6 +19,19 @@ module StoreModel
19
19
  base.extend StoreModel::TypeBuilders
20
20
 
21
21
  base.attribute_method_suffix "?"
22
+
23
+ base.extend(ClassMethods)
24
+ end
25
+
26
+ # Class methods for StoreModel::Model
27
+ module ClassMethods
28
+ def from_value(value)
29
+ to_type.cast_value(value)
30
+ end
31
+
32
+ def from_values(values)
33
+ to_array_type.cast_value(values)
34
+ end
22
35
  end
23
36
 
24
37
  attr_accessor :parent
@@ -8,6 +8,17 @@ module StoreModel
8
8
  end
9
9
 
10
10
  module ClassMethods # :nodoc:
11
+ # gather storemodel attribute types on the class-level
12
+ def store_model_attribute_types
13
+ @store_model_attribute_types ||= {}
14
+ end
15
+
16
+ # add storemodel type of attribute if it is storemodel type
17
+ def attribute(name, type = nil, **)
18
+ store_model_attribute_types[name.to_s] = type if type.is_a?(Types::Base)
19
+ super
20
+ end
21
+
11
22
  # Enables handling of nested StoreModel::Model attributes
12
23
  #
13
24
  # @param associations [Array] list of associations and options to define attributes, for example:
@@ -38,8 +49,7 @@ module StoreModel
38
49
  options = attributes.extract_options!
39
50
 
40
51
  attributes.each do |attribute|
41
- case nested_attribute_type(attribute)
42
- when Types::OneBase, Types::ManyBase
52
+ if nested_attribute_type(attribute).is_a?(Types::Base)
43
53
  options.reverse_merge!(allow_destroy: false, update_only: false)
44
54
  define_store_model_attr_accessors(attribute, options)
45
55
  else
@@ -50,17 +60,19 @@ module StoreModel
50
60
 
51
61
  private
52
62
 
53
- # If attribute defined in ActiveRecord model but you dont yet have database created
54
- # you cannot access attribute types.
55
- # To handle this case, we can use ActiveRecord::Attributes 'attributes_to_define_after_schema_loads'
56
- # which stores information about custom defined attributes.
57
- # See ActiveRecord::Attributes#atribute
58
- # If #accepts_nested_attributes_for is used inside active model instance
59
- # schema is not required to determine attribute type so we can still use attribute_types
60
- # If schema loaded the attribute_types already populated and we can safely use it
61
- # See ActiveRecord::ModelSchema#load_schema!
63
+ # when db connection is not available, it becomes impossible to read attributes types from
64
+ # ActiveModel::AttributeRegistration::ClassMethods.attribute_types, because activerecord
65
+ # overrides _default_attributes and triggers db connection.
66
+ # for activerecord model only use attribute_types if it has db connected
67
+ #
68
+ # @param attribute [String, Symbol]
69
+ # @return [StoreModel::Types::Base, nil]
62
70
  def nested_attribute_type(attribute)
63
- attribute_types[attribute.to_s]
71
+ if self < ActiveRecord::Base && !schema_loaded?
72
+ store_model_attribute_types[attribute.to_s]
73
+ else
74
+ attribute_types[attribute.to_s]
75
+ end
64
76
  end
65
77
 
66
78
  def define_store_model_attr_accessors(attribute, options) # rubocop:disable Metrics/MethodLength
@@ -121,12 +133,12 @@ module StoreModel
121
133
  end
122
134
  end
123
135
 
124
- attributes.reject! { |attribute| call_reject_if(attribute, options[:reject_if]) } if options&.dig(:reject_if)
136
+ attributes.reject! { call_store_model_reject_if(_1, options[:reject_if]) } if options&.dig(:reject_if)
125
137
 
126
138
  send("#{association}=", attributes)
127
139
  end
128
140
 
129
- def call_reject_if(attributes, callback)
141
+ def call_store_model_reject_if(attributes, callback)
130
142
  callback = ActiveRecord::NestedAttributes::ClassMethods::REJECT_ALL_BLANK_PROC if callback == :all_blank
131
143
 
132
144
  case callback
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model"
4
+
5
+ module StoreModel
6
+ module Types
7
+ # Base type for StoreModel::Model
8
+ class Base < ActiveModel::Type::Value
9
+ attr_reader :model_klass
10
+
11
+ # Returns type
12
+ #
13
+ # @return [Symbol]
14
+ def type
15
+ raise NotImplementedError
16
+ end
17
+
18
+ protected
19
+
20
+ def raise_cast_error(_value)
21
+ raise NotImplementedError
22
+ end
23
+ end
24
+ end
25
+ end
@@ -34,7 +34,7 @@ module StoreModel
34
34
 
35
35
  case value
36
36
  when String, Symbol then cast_symbol_value(value)
37
- when Integer then cast_integer_value(value)
37
+ when Integer, Float then cast_integer_value(value)
38
38
  else
39
39
  raise StoreModel::Types::CastError,
40
40
  "failed casting #{value.inspect}, only String, Symbol or " \
@@ -4,18 +4,8 @@ require "active_model"
4
4
 
5
5
  module StoreModel
6
6
  module Types
7
- # Implements ActiveModel::Type::Value type for handling an array of
8
- # StoreModel::Model
9
- class ManyBase < ActiveModel::Type::Value
10
- attr_reader :model_klass
11
-
12
- # Returns type
13
- #
14
- # @return [Symbol]
15
- def type
16
- raise NotImplementedError
17
- end
18
-
7
+ # Implements type for handling an array of StoreModel::Model
8
+ class ManyBase < Base
19
9
  # Casts +value+ from DB or user to StoreModel::Model instance
20
10
  #
21
11
  # @param value [Object] a value to cast
@@ -70,10 +60,6 @@ module StoreModel
70
60
  raise NotImplementedError
71
61
  end
72
62
 
73
- def raise_cast_error(_value)
74
- raise NotImplementedError
75
- end
76
-
77
63
  private
78
64
 
79
65
  # rubocop:disable Style/RescueModifier
@@ -4,17 +4,8 @@ require "active_model"
4
4
 
5
5
  module StoreModel
6
6
  module Types
7
- # Implements ActiveModel::Type::Value type for handling an instance of StoreModel::Model
8
- class OneBase < ActiveModel::Type::Value
9
- attr_reader :model_klass
10
-
11
- # Returns type
12
- #
13
- # @return [Symbol]
14
- def type
15
- raise NotImplementedError
16
- end
17
-
7
+ # Implements type for handling an instance of StoreModel::Model
8
+ class OneBase < Base
18
9
  # Casts +value+ from DB or user to StoreModel::Model instance
19
10
  #
20
11
  # @param value [Object] a value to cast
@@ -36,10 +27,6 @@ module StoreModel
36
27
 
37
28
  protected
38
29
 
39
- def raise_cast_error(_value)
40
- raise NotImplementedError
41
- end
42
-
43
30
  def model_instance(_value)
44
31
  raise NotImplementedError
45
32
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "store_model/types/polymorphic_helper"
4
+ require "store_model/types/base"
4
5
 
5
6
  require "store_model/types/one_base"
6
7
  require "store_model/types/one"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StoreModel # :nodoc:
4
- VERSION = "4.0.0"
4
+ VERSION = "4.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: store_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-06 00:00:00.000000000 Z
11
+ date: 2024-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -92,6 +92,7 @@ files:
92
92
  - lib/store_model/railtie.rb
93
93
  - lib/store_model/type_builders.rb
94
94
  - lib/store_model/types.rb
95
+ - lib/store_model/types/base.rb
95
96
  - lib/store_model/types/enum_type.rb
96
97
  - lib/store_model/types/many.rb
97
98
  - lib/store_model/types/many_base.rb