active_record_compose 0.1.7 → 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: bff1c2fd72a225a89ada1c0cab86b6d32f31c0052d8857e665eb2796f4a40883
4
- data.tar.gz: 307e8ecf50282b9a19e224870796944de47d37f8802d0ffe63cca465eb663cc4
3
+ metadata.gz: 6693618ddc81944ece9c991f800ba8ce1ef5b7f462b13bfe0c9f4b03b04bdc6f
4
+ data.tar.gz: 36cc7ec0a5852c409dab736d21058f2538c3a656e893d37a7ec8bf2ae499f2cb
5
5
  SHA512:
6
- metadata.gz: 12f503a644d60932a095a587e8152d37af25b8eccfb0cc5cd32dc5941eb896104880328ff6e3ed2b7fd53ee78fad9f7962e23b5ffc1070bbaa00518e482dccf4
7
- data.tar.gz: 91d912f794a250e44e8ad5fea2694f00a52eb98df3f217364e8eb637a6971692998526e86c2d908dc28ce7b0ff99ada394ca287b39342714377af63a1869c4be
6
+ metadata.gz: 2780e3749043f5667bcd1a693c248f0c3f2378f7cb8d221f636ada171ab4c5b03c7baa2c479e381ab73570352fabd5c1fb623d9d3ca79b8718919bbe77f5fffe
7
+ data.tar.gz: 4f6eec237d85851c0eb6041dacb2ea8c2000c431bfe4c632e11647e3009a0d9745bcb572b492ff71e07baa03c298faecb9406d76b939468f0d21cb4315c3eb04
data/.rubocop.yml CHANGED
@@ -3,6 +3,9 @@ AllCops:
3
3
  NewCops: enable
4
4
  SuggestExtensions: false
5
5
 
6
+ Style/ArgumentsForwarding:
7
+ Enabled: false
8
+
6
9
  Style/Documentation:
7
10
  Enabled: false
8
11
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-01-21
4
+
5
+ - add i18n doc.
6
+ - add sig/
7
+ - add typecheck for ci.
8
+
9
+ ## [0.1.8] - 2024-01-16
10
+
11
+ - avoid executing `#save!` from `Model#save`
12
+ - on save, ignore nil elements from models.
13
+
3
14
  ## [0.1.7] - 2024-01-15
4
15
 
5
16
  - remove `add_development_dependency` from gemspec
data/README.md CHANGED
@@ -271,6 +271,30 @@ model.update
271
271
  # after_save called!
272
272
  ```
273
273
 
274
+ ### I18n
275
+
276
+ When the `#save!` operation raises an `ActiveRecord::RecordInvalid` exception, it is necessary to have pre-existing locale definitions in order to construct i18n information correctly.
277
+ The specific keys required are `activemodel.errors.messages.record_invalid` or `errors.messages.record_invalid`.
278
+
279
+ (Replace `en` as appropriate in the context.)
280
+
281
+ ```yaml
282
+ en:
283
+ activemodel:
284
+ errors:
285
+ messages:
286
+ record_invalid: 'Validation failed: %{errors}'
287
+ ```
288
+
289
+ Alternatively, the following definition is also acceptable:
290
+
291
+ ```yaml
292
+ en:
293
+ errors:
294
+ messages:
295
+ record_invalid: 'Validation failed: %{errors}'
296
+ ```
297
+
274
298
  ## Development
275
299
 
276
300
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -63,7 +63,11 @@ module ActiveRecordCompose
63
63
  #
64
64
  # @return [Hash] hash with the attribute name as key and the attribute value as value.
65
65
  def attributes
66
- (defined?(super) ? super : {}).merge(delegated_attributes.to_h { [_1, public_send(_1)] })
66
+ # steep:ignore all
67
+ attrs = defined?(super) ? super : {}
68
+ # steep:ignore end
69
+ # @type var attrs: Hash[String, untyped]
70
+ attrs.merge(delegated_attributes.to_h { [_1, public_send(_1)] })
67
71
  end
68
72
  end
69
73
  end
@@ -16,7 +16,8 @@ module ActiveRecordCompose
16
16
 
17
17
  # @return [Symbol] :save or :destroy
18
18
  def context
19
- ret = @context.respond_to?(:call) ? @context.call(model) : @context
19
+ c = @context
20
+ ret = c.is_a?(Proc) ? c.call(model) : c
20
21
  ret.presence_in(%i[save destroy]) || :save
21
22
  end
22
23
 
@@ -73,7 +73,7 @@ module ActiveRecordCompose
73
73
  def __each_by_wrapped
74
74
  return enum_for(:__each_by_wrapped) unless block_given?
75
75
 
76
- models.each { yield _1 }
76
+ models.each { yield _1 if _1.__raw_model }
77
77
  self
78
78
  end
79
79
 
@@ -19,7 +19,9 @@ module ActiveRecordCompose
19
19
  validate :validate_models
20
20
 
21
21
  def initialize(attributes = {})
22
+ # steep:ignore all
22
23
  super(attributes)
24
+ # steep:ignore end
23
25
  end
24
26
 
25
27
  # Save the models that exist in models.
@@ -31,7 +33,7 @@ module ActiveRecordCompose
31
33
  def save
32
34
  return false if invalid?
33
35
 
34
- save_in_transaction { save_models }
36
+ save_in_transaction { save_models(bang: false) }
35
37
  end
36
38
 
37
39
  # Save the models that exist in models.
@@ -42,7 +44,7 @@ module ActiveRecordCompose
42
44
  def save!
43
45
  valid? || raise_validation_error
44
46
 
45
- save_in_transaction { save_models } || raise_on_save_error
47
+ save_in_transaction { save_models(bang: true) } || raise_on_save_error
46
48
  end
47
49
 
48
50
  # Behavior is same to `#save`, but `before_create` and `after_create` hooks fires.
@@ -74,7 +76,7 @@ module ActiveRecordCompose
74
76
  assign_attributes(attributes)
75
77
  return false if invalid?
76
78
 
77
- save_in_transaction { run_callbacks(:create) { save_models } }
79
+ save_in_transaction { run_callbacks(:create) { save_models(bang: false) } }
78
80
  end
79
81
 
80
82
  # Behavior is same to `#create`, but raises an exception prematurely on failure.
@@ -83,7 +85,7 @@ module ActiveRecordCompose
83
85
  assign_attributes(attributes)
84
86
  valid? || raise_validation_error
85
87
 
86
- save_in_transaction { run_callbacks(:create) { save_models } } || raise_on_save_error
88
+ save_in_transaction { run_callbacks(:create) { save_models(bang: true) } } || raise_on_save_error
87
89
  end
88
90
 
89
91
  # Behavior is same to `#save`, but `before_update` and `after_update` hooks fires.
@@ -115,7 +117,7 @@ module ActiveRecordCompose
115
117
  assign_attributes(attributes)
116
118
  return false if invalid?
117
119
 
118
- save_in_transaction { run_callbacks(:update) { save_models } }
120
+ save_in_transaction { run_callbacks(:update) { save_models(bang: false) } }
119
121
  end
120
122
 
121
123
  # Behavior is same to `#update`, but raises an exception prematurely on failure.
@@ -124,7 +126,7 @@ module ActiveRecordCompose
124
126
  assign_attributes(attributes)
125
127
  valid? || raise_validation_error
126
128
 
127
- save_in_transaction { run_callbacks(:update) { save_models } } || raise_on_save_error
129
+ save_in_transaction { run_callbacks(:update) { save_models(bang: true) } } || raise_on_save_error
128
130
  end
129
131
 
130
132
  private
@@ -149,7 +151,7 @@ module ActiveRecordCompose
149
151
  end.present?
150
152
  end
151
153
 
152
- def save_models = wrapped_models.all? { _1.save! }
154
+ def save_models(bang:) = wrapped_models.all? { bang ? _1.save! : _1.save }
153
155
 
154
156
  def raise_validation_error = raise ActiveRecord::RecordInvalid, self
155
157
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
- VERSION = '0.1.7'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -0,0 +1,100 @@
1
+ # TypeProf 0.21.9
2
+
3
+ # Classes
4
+ module ActiveRecordCompose
5
+ VERSION: String
6
+
7
+ interface _ARLike
8
+ def is_a?: (untyped) -> bool
9
+ def save: -> bool
10
+ def save!: -> untyped
11
+ def destroy: -> bool
12
+ def destroy!: -> untyped
13
+ def invalid?: -> bool
14
+ def valid?: -> bool
15
+ def errors: -> untyped
16
+ def ==: (untyped) -> bool
17
+ end
18
+
19
+ type attribute_name = (String | Symbol)
20
+ type context_types = (:save | :destroy)
21
+ type context_proc = ^(_ARLike) -> context_types
22
+ type context = context_types | context_proc
23
+
24
+ module DelegateAttribute
25
+ extend ActiveSupport::Concern
26
+
27
+ def delegated_attribute: -> Array[untyped]
28
+ def attributes: -> Hash[String, untyped]
29
+ def delegated_attributes: -> Array[untyped]
30
+ def delegated_attributes=: (Array[untyped]) -> void
31
+
32
+ def self.class_attribute: (untyped, ?untyped) -> untyped
33
+ def delegate: (*untyped) -> untyped
34
+ end
35
+
36
+ class InnerModelCollection
37
+ include ::Enumerable[_ARLike]
38
+ @models: Array[InnerModel]
39
+
40
+ def each: () { (_ARLike) -> void } -> InnerModelCollection | () -> Enumerator[_ARLike, self]
41
+ def <<: (_ARLike) -> self
42
+ def push: (_ARLike, ?context: context) -> self
43
+ def empty?: -> bool
44
+ def clear: -> self
45
+ def delete: (_ARLike | InnerModel, ?context: context_types) -> InnerModelCollection?
46
+ def __each_by_wrapped: () { (InnerModel) -> void } -> InnerModelCollection | () -> Enumerator[InnerModel, self]
47
+
48
+ private
49
+ def models: -> Array[InnerModel]
50
+ def wrap: (_ARLike | InnerModel, context: context) -> InnerModel
51
+ end
52
+
53
+ class InnerModel
54
+ @context: context
55
+
56
+ def initialize: (_ARLike, ?context: context) -> void
57
+ def context: -> context
58
+ def save: -> bool
59
+ def save!: -> untyped
60
+ def invalid?: -> bool
61
+ def valid?: -> bool
62
+ def ==: (untyped) -> bool
63
+ def __raw_model: -> _ARLike
64
+
65
+ private
66
+ attr_reader model: _ARLike
67
+ end
68
+
69
+ class Model
70
+ extend ActiveModel::Callbacks
71
+ include ActiveModel::Model
72
+ include ActiveModel::Validations::Callbacks
73
+ include ActiveModel::Attributes
74
+ include ActiveRecord::Transactions
75
+ include DelegateAttribute
76
+
77
+ @__models: InnerModelCollection
78
+
79
+ def initialize: (?Hash[attribute_name, untyped]) -> void
80
+ def save: -> bool
81
+ def save!: -> untyped
82
+ def create: (?Hash[attribute_name, untyped]) -> bool
83
+ def create!: (?Hash[attribute_name, untyped]) -> untyped
84
+ def update: (?Hash[attribute_name, untyped]) -> bool
85
+ def update!: (?Hash[attribute_name, untyped]) -> untyped
86
+
87
+ private
88
+ def models: -> InnerModelCollection
89
+ def wrapped_models: -> Enumerator[InnerModel, InnerModelCollection]
90
+ def validate_models: -> void
91
+ def save_in_transaction: { -> bool } -> untyped
92
+ def save_models: (bang: bool) -> bool
93
+ def raise_validation_error: -> bot
94
+ def raise_on_save_error: -> bot
95
+ def raise_on_save_error_message: -> String
96
+
97
+ def self.validate: (*untyped) -> untyped
98
+ def run_callbacks: (untyped kind) ?{ () -> untyped } -> untyped
99
+ end
100
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamajyotan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-14 00:00:00.000000000 Z
11
+ date: 2024-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -37,13 +37,13 @@ files:
37
37
  - CODE_OF_CONDUCT.md
38
38
  - LICENSE.txt
39
39
  - README.md
40
- - Rakefile
41
40
  - lib/active_record_compose.rb
42
41
  - lib/active_record_compose/delegate_attribute.rb
43
42
  - lib/active_record_compose/inner_model.rb
44
43
  - lib/active_record_compose/inner_model_collection.rb
45
44
  - lib/active_record_compose/model.rb
46
45
  - lib/active_record_compose/version.rb
46
+ - sig/active_record_compose.rbs
47
47
  homepage: https://github.com/hamajyotan/active_record_compose
48
48
  licenses:
49
49
  - MIT
@@ -51,7 +51,7 @@ metadata:
51
51
  homepage_uri: https://github.com/hamajyotan/active_record_compose
52
52
  source_code_uri: https://github.com/hamajyotan/active_record_compose
53
53
  changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
54
- documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.1.7
54
+ documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.2.0
55
55
  rubygems_mfa_required: 'true'
56
56
  post_install_message:
57
57
  rdoc_options: []
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  requirements: []
71
- rubygems_version: 3.4.10
71
+ rubygems_version: 3.5.5
72
72
  signing_key:
73
73
  specification_version: 4
74
74
  summary: activemodel form object pattern
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require 'rubocop/rake_task'
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]