active_record_compose 0.10.0 → 0.11.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: c78fcb982e3f8f36a5497483ae835eaba9724d72342efc0866ca596c25fa45a8
4
- data.tar.gz: 515f08b1def287d06c1d8436a0c3cb466ef75016094e4778b0e9ba992c95cc30
3
+ metadata.gz: eae661ba621f2e95a089f01a029aa1918af952588e2a0204a8124e1c48aeecc3
4
+ data.tar.gz: '0208e91c70ea06235a2870901fcae2dfda328b8877b4ab9d776b14cd4e1de322'
5
5
  SHA512:
6
- metadata.gz: 1976cef02cc6dbf8d9d543b339254136733c580f116f2ad38c1239fd7a18bdf9a2bde27d7a22be4f041c0eb2576f1bbc97d6e18cfd5859dae52fb2a90624ab69
7
- data.tar.gz: 71130efd7792fa18dc33903d12bd6eb7ac17ac59bff95ceeedb2200ce128c3f34fdc7229866f8b5fbeea68f1136bb84dd35a17e2e0167b5990d2b26723022ba3
6
+ metadata.gz: 0e535cd4c0cc88700fbb50846db582848dd13b612274328a60382963ace26fafa06feb8ad9c724e95f4f48d257c2877ce2d74f828671f33639d533a341be2c37
7
+ data.tar.gz: 24ad34a3fd2b608c7f266f09417f9aeca97c494dcedd9b233a83eb5f2d6bb04e2f867acf1eb7260749886dbbbdce3f458885861277cd36dd34087ac7d7b33b8e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.11.0] - 2025-05-30
4
+
5
+ - `#attribute_names` now takes into account attributes declared in `.delegate_attribute`
6
+ - Implemented query methods with a `?` suffix for each attribute.
7
+ Their evaluation behavior is consistent with ActiveRecord.
8
+ For example:
9
+ - Defining `attribute :foo` allows calling `model.foo?`.
10
+ - Defining `delegate_attribute :bar, to: :other` allows calling `model.bar?`.
11
+
3
12
  ## [0.10.0] - 2025-04-07
4
13
 
5
14
  - avoid twice validation. As a side effect, save must accept argument `#save(**options)`.
data/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  activemodel (activerecord) form object pattern. it embraces multiple AR models and provides a transparent interface as if they were a single model.
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/active_record_compose.svg)](https://badge.fury.io/rb/active_record_compose)
5
6
  ![CI](https://github.com/hamajyotan/active_record_compose/workflows/CI/badge.svg)
7
+ [![DeepWiki](https://img.shields.io/badge/DeepWiki-hamajyotan%2Factive__record__compose-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/hamajyotan/active_record_compose)
8
+
9
+
6
10
 
7
11
  ## Table of Contents
8
12
 
@@ -17,6 +21,7 @@ activemodel (activerecord) form object pattern. it embraces multiple AR models a
17
21
  - [`destroy` option](#destroy-option)
18
22
  - [Callback ordering by `#persisted?`](#callback-ordering-by-persisted)
19
23
  - [`#save` with custom context option](#save-with-custom-context-option)
24
+ - [Sample application as an example](#sample-application-as-an-example)
20
25
  - [Links](#links)
21
26
  - [Development](#development)
22
27
  - [Contributing](#contributing)
@@ -394,10 +399,15 @@ r.save(context: :education)
394
399
  => true
395
400
  ```
396
401
 
402
+ ## Sample application as an example
403
+
404
+ With Github Codespaces, it can also be run directly in the browser. Naturally, a local environment is also possible.
405
+
406
+ - https://github.com/hamajyotan/active_record_compose-example
407
+
397
408
  ## Links
398
409
 
399
410
  - [Smart way to update multiple models simultaneously in Rails](https://dev.to/hamajyotan/smart-way-to-update-multiple-models-simultaneously-in-rails-51b6)
400
- - [Sample application as an example](https://github.com/hamajyotan/active_record_compose-example)
401
411
 
402
412
  ## Development
403
413
 
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecordCompose
4
+ # = Attribute \Querying
5
+ #
6
+ # This provides predicate methods based on the attributes.
7
+ #
8
+ # class AccountRegistration < ActiveRecordCompose::Model
9
+ # def initialize
10
+ # @account = Account.new
11
+ # super()
12
+ # models << account
13
+ # end
14
+ #
15
+ # attribute :original_attr
16
+ # delegate_attribute :name, :email, to: :account
17
+ #
18
+ # private
19
+ #
20
+ # attr_reader :account
21
+ # end
22
+ #
23
+ # model = AccountRegistration.new
24
+ #
25
+ # model.name #=> nil
26
+ # model.name? #=> false
27
+ # model.name = 'Alice'
28
+ # model.name? #=> true
29
+ #
30
+ # model.original_attr = "Bob"
31
+ # model.original_attr? #=> true
32
+ # model.original_attr = ""
33
+ # model.original_attr? #=> false
34
+ #
35
+ # # If the value is numeric, it returns the result of checking whether it is zero or not.
36
+ # # This behavior is consistent with `ActiveRecord::AttributeMethods::Query`.
37
+ # model.original_attr = 123
38
+ # model.original_attr? #=> true
39
+ # model.original_attr = 0
40
+ # model.original_attr? #=> false
41
+ #
42
+ module AttributeQuerying
43
+ extend ActiveSupport::Concern
44
+
45
+ included do
46
+ attribute_method_suffix '?', parameters: false
47
+ end
48
+
49
+ private
50
+
51
+ def attribute?(attr_name)
52
+ value = public_send(attr_name)
53
+
54
+ case value
55
+ when true then true
56
+ when false, nil then false
57
+ else
58
+ if value.respond_to?(:zero?)
59
+ !value.zero?
60
+ else
61
+ value.present?
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -58,6 +58,12 @@ module ActiveRecordCompose
58
58
  end
59
59
  end
60
60
 
61
+ # Returns a array of attribute name.
62
+ # Attributes declared with `delegate_attribute` are also merged.
63
+ #
64
+ # @return [Array<String>] array of attribute name.
65
+ def attribute_names = super + delegated_attributes
66
+
61
67
  # Returns a hash with the attribute name as key and the attribute value as value.
62
68
  # Attributes declared with `delegate_attribute` are also merged.
63
69
  #
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_record_compose/callbacks'
4
+ require 'active_record_compose/attribute_querying'
4
5
  require 'active_record_compose/composed_collection'
5
6
  require 'active_record_compose/delegate_attribute'
6
7
  require 'active_record_compose/transaction_support'
@@ -14,6 +15,7 @@ module ActiveRecordCompose
14
15
  include ActiveModel::Validations::Callbacks
15
16
  include ActiveModel::Attributes
16
17
 
18
+ include ActiveRecordCompose::AttributeQuerying
17
19
  include ActiveRecordCompose::Callbacks
18
20
  include ActiveRecordCompose::DelegateAttribute
19
21
  include ActiveRecordCompose::TransactionSupport
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
- VERSION = '0.10.0'
4
+ VERSION = '0.11.0'
5
5
  end
@@ -1,4 +1,12 @@
1
1
  module ActiveRecordCompose
2
+ module AttributeQuerying
3
+ extend ActiveSupport::Concern
4
+ extend ActiveModel::AttributeMethods::ClassMethods
5
+
6
+ private
7
+ def attribute?: (attribute_name) -> untyped
8
+ end
9
+
2
10
  module Callbacks
3
11
  include ActiveModel::Model
4
12
  include ActiveModel::Validations::Callbacks
@@ -31,7 +39,6 @@ module ActiveRecordCompose
31
39
  module DelegateAttribute : ActiveModel::Attributes
32
40
  extend ActiveSupport::Concern
33
41
 
34
- def attributes: -> Hash[String, untyped]
35
42
  def delegated_attributes: () -> Array[String]
36
43
 
37
44
  module ClassMethods : Module
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamajyotan
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-07 00:00:00.000000000 Z
10
+ date: 2025-05-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activerecord
@@ -37,6 +37,7 @@ files:
37
37
  - LICENSE.txt
38
38
  - README.md
39
39
  - lib/active_record_compose.rb
40
+ - lib/active_record_compose/attribute_querying.rb
40
41
  - lib/active_record_compose/callbacks.rb
41
42
  - lib/active_record_compose/composed_collection.rb
42
43
  - lib/active_record_compose/delegate_attribute.rb
@@ -54,7 +55,7 @@ metadata:
54
55
  homepage_uri: https://github.com/hamajyotan/active_record_compose
55
56
  source_code_uri: https://github.com/hamajyotan/active_record_compose
56
57
  changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
57
- documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.10.0
58
+ documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.11.0
58
59
  rubygems_mfa_required: 'true'
59
60
  rdoc_options: []
60
61
  require_paths: