store_model 2.1.1 → 2.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: a3b12509ebafeb20d7a2bcb2ae1094dcd756f1b86f31dd8066b0abd61d8f998a
4
- data.tar.gz: d3a06944b46ebf4094de55736e892f15ae27514e0604047260e74a033bbc7cda
3
+ metadata.gz: 02f882325fbae00f97a61603cdab0578ccfd1723a54b8b6e4cfd61aeaabe8a6f
4
+ data.tar.gz: bfd3a7c92a01debecb1fea0d36f73306486612ec7cba22095f9673907ae6b9e4
5
5
  SHA512:
6
- metadata.gz: 7d8ec95caf59aea39e3cedc20a471db9289f4c1eda9d083a1b2fd321f732e7d056b67ac58a7f4f437cb04e932c1f14f18e56dfb9b04c884e5d64025cc7d7989b
7
- data.tar.gz: e526dbc89d1c4186b1fe94581acb2b1d80e207bcf08d69809dffc393d43e3d8d2cd08c905d3d3d4f842c9bf7db9ad1581611368fabe8206eb0445c16a2c615eb
6
+ metadata.gz: d8a703611d38eedfa8d66e5db71084df8a89676e8f6401207451160278ec4df9c7274acab73027d6eba9c6bcb884c77ebd06c420fc08dd592ea423b7e45f9821
7
+ data.tar.gz: c2a876abb12ccd218c40f0e0d9d89613ea03f0d318f7dcffb83c85ea6f6cee3bebc52caf8ae2cf21bc0bc37969d271d04d61a6199d08865ab54ce40277f36a91
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # StoreModel [![Gem Version](https://badge.fury.io/rb/store_model.svg)](https://rubygems.org/gems/store_model) [![Coverage Status](https://coveralls.io/repos/github/DmitryTsepelev/store_model/badge.svg?branch=master)](https://coveralls.io/github/DmitryTsepelev/store_model?branch=master) ![](https://ruby-gem-downloads-badge.herokuapp.com/store_model?type=total)
1
+ # StoreModel [![Gem Version](https://badge.fury.io/rb/store_model.svg)](https://rubygems.org/gems/store_model) ![](https://ruby-gem-downloads-badge.herokuapp.com/store_model?type=total)
2
2
 
3
3
  **StoreModel** gem allows you to wrap JSON-backed DB columns with ActiveModel-like classes.
4
4
 
@@ -118,7 +118,7 @@ module StoreModel
118
118
  #
119
119
  # @return [String]
120
120
  def inspect
121
- attribute_string = attributes.map { |name, value| "#{name}: #{value.nil? ? 'nil' : value}" }
121
+ attribute_string = attributes.map { |name, value| "#{name}: #{value.inspect}" }
122
122
  .join(", ")
123
123
  "#<#{self.class.name} #{attribute_string}>"
124
124
  end
@@ -35,25 +35,45 @@ module StoreModel
35
35
  #
36
36
  # See https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for
37
37
  def accepts_nested_attributes_for(*attributes)
38
- global_options = attributes.extract_options!
38
+ options = attributes.extract_options!
39
39
 
40
- attributes.each do |attribute, options|
41
- case attribute_types[attribute.to_s]
40
+ attributes.each do |attribute|
41
+ case nested_attribute_type(attribute)
42
42
  when Types::OneBase, Types::ManyBase
43
- define_store_model_attr_accessors(attribute, options || global_options)
43
+ options.reverse_merge!(allow_destroy: false, update_only: false)
44
+ define_store_model_attr_accessors(attribute, options)
44
45
  else
45
- super(attribute, options || global_options)
46
+ super(*attribute, options)
46
47
  end
47
48
  end
48
49
  end
49
50
 
50
51
  private
51
52
 
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!
62
+ def nested_attribute_type(attribute)
63
+ if self < ActiveRecord::Base && !schema_loaded?
64
+ attributes_to_define_after_schema_loads[attribute.to_s]&.first
65
+ else
66
+ attribute_types[attribute.to_s]
67
+ end
68
+ end
69
+
52
70
  def define_store_model_attr_accessors(attribute, options)
53
- case attribute_types[attribute.to_s]
71
+ case nested_attribute_type(attribute)
54
72
  when Types::OneBase
55
73
  define_association_setter_for_single(attribute, options)
56
- alias_method "#{attribute}_attributes=", "#{attribute}="
74
+ define_method "#{attribute}_attributes=" do |*args, **kwargs|
75
+ send("#{attribute}=", *args, **kwargs)
76
+ end
57
77
  when Types::ManyBase
58
78
  define_association_setter_for_many(attribute, options)
59
79
  end
@@ -64,7 +84,7 @@ module StoreModel
64
84
  def define_attr_accessor_for_destroy(association, options)
65
85
  return unless options&.dig(:allow_destroy)
66
86
 
67
- attribute_types[association.to_s].model_klass.class_eval do
87
+ nested_attribute_type(association).model_klass.class_eval do
68
88
  attr_accessor :_destroy
69
89
  end
70
90
  end
@@ -88,7 +108,10 @@ module StoreModel
88
108
  end
89
109
  end
90
110
 
91
- def assign_nested_attributes_for_collection_association(association, attributes, options)
111
+ # Base
112
+ def assign_nested_attributes_for_collection_association(association, attributes, options = nil)
113
+ return super(association, attributes) unless options
114
+
92
115
  attributes = attributes.values if attributes.is_a?(Hash)
93
116
 
94
117
  if options&.dig(:allow_destroy)
@@ -63,7 +63,7 @@ module StoreModel
63
63
  def deserialize(value)
64
64
  case value
65
65
  when String
66
- payload = ActiveSupport::JSON.decode(value) rescue nil
66
+ payload = ActiveSupport::JSON.decode(value) rescue {}
67
67
  model_instance(deserialize_by_types(payload))
68
68
  when Hash
69
69
  model_instance(deserialize_by_types(value))
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StoreModel # :nodoc:
4
- VERSION = "2.1.1"
4
+ VERSION = "2.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: 2.1.1
4
+ version: 2.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: 2023-08-29 00:00:00.000000000 Z
11
+ date: 2024-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.64.0
69
- - !ruby/object:Gem::Dependency
70
- name: coveralls
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
69
  description: Gem for working with JSON-backed attributes as ActiveRecord models
84
70
  email:
85
71
  - dmitry.a.tsepelev@gmail.com