active_type 2.6.4 → 2.7.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: 7a0b2f6fb30a96dbcbbbce17bd19e3476ff6aa723506c511992a2635a6871d97
4
- data.tar.gz: ea1191cda8575afdcb7b912d3f921f2d5b8f0fe3dc9f7ffca0547d86693d5d1e
3
+ metadata.gz: f11ea5914e78ff48fe20270960c6e8b6062b22b87752eb814f2e7c935257a60a
4
+ data.tar.gz: 3bd47fa49ec42f7cae09ec396a7442df2ecfd9840ee087e9531c359e20d88a64
5
5
  SHA512:
6
- metadata.gz: 012e905251e98a6da960f5c1f04ca30d55d6af090812e31e5bb13dfa4832128d9cfd9128552a5e2118d23d97e09016070c094d46d39e0101f15df8e61d66914c
7
- data.tar.gz: 62a7496d44a532065c92cf4b8d75971cb3333eb82d7456a6fa9d31529f40327cf720a7115859319dc79182a2020987e7a23512f1551ab36b9336e82241ab02b1
6
+ metadata.gz: f74d712d4f74b4d7b7e212b0280b4bfff20245a9ed8430445a38cdf3c30017cb48121f109f0a150bf8cdb82d86700867618e3407e3c82ff8abc74ffe83ff493d
7
+ data.tar.gz: 5b21a579e4e1de11547f94215d9b69c02dcb442f2dc42b915ced261f5f0661f213d440bcf5c26f65006e474b7ad74118b71b6e674856dd7682af484d6db3a936
@@ -14,9 +14,7 @@ jobs:
14
14
  fail-fast: false
15
15
  matrix:
16
16
  include:
17
- - ruby: "2.7.8"
18
- gemfile: Gemfile.6.1.sqlite3
19
- - ruby: "3.0.7"
17
+ - ruby: "3.1.6"
20
18
  gemfile: Gemfile.7.1.sqlite3
21
19
  - ruby: "3.1.6"
22
20
  gemfile: Gemfile.7.2.sqlite3
@@ -24,6 +22,8 @@ jobs:
24
22
  gemfile: Gemfile.7.2.sqlite3
25
23
  - ruby: "3.3.6"
26
24
  gemfile: Gemfile.8.0.sqlite3
25
+ - ruby: "3.4.7"
26
+ gemfile: Gemfile.8.1.sqlite3
27
27
  env:
28
28
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
29
29
 
@@ -96,12 +96,10 @@ jobs:
96
96
  fail-fast: false
97
97
  matrix:
98
98
  include:
99
- - ruby: "3.0.7"
100
- gemfile: Gemfile.6.1.pg
101
- - ruby: "3.2.6"
102
- gemfile: Gemfile.7.1.pg
103
99
  - ruby: "3.2.6"
104
100
  gemfile: Gemfile.7.2.pg
101
+ - ruby: "3.4.7"
102
+ gemfile: Gemfile.8.1.pg
105
103
  env:
106
104
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
107
105
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2
1
+ 3.4
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 2.7.0 (2025-11-03)
6
+ * Removed: Support for Ruby < 3.1, Rails < 7.
7
+ * Fixed: Exception when using ActiveType::Record with Rails 8.1.
8
+
9
+ ## 2.6.5 (2025-10-16)
10
+
11
+ * Fixed: ActiveType::Object and ActiveType::Record are now serialized/deserialized correctly using Marshal.dump/Marshal.load
12
+
5
13
  ## 2.6.4 (2025-09-11)
6
14
 
7
15
  * Fixed: When using nests_many, nested updates, with preloaded records, using string ids will no longer cause additional DB queries.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_type (2.6.3)
4
+ active_type (2.7.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_type (2.6.3)
4
+ active_type (2.7.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
data/Gemfile.7.2.pg.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_type (2.6.3)
4
+ active_type (2.7.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_type (2.6.3)
4
+ active_type (2.7.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_type (2.6.3)
4
+ active_type (2.7.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'activerecord', '~>6.1.0'
3
+ gem 'activerecord', '~>8.1.0'
4
4
  gem 'rspec', '~>3.4'
5
5
  gem 'pg'
6
6
  gem 'rake'
@@ -0,0 +1,86 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ active_type (2.7.0)
5
+ activerecord (>= 6.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (8.1.0)
11
+ activesupport (= 8.1.0)
12
+ activerecord (8.1.0)
13
+ activemodel (= 8.1.0)
14
+ activesupport (= 8.1.0)
15
+ timeout (>= 0.4.0)
16
+ activesupport (8.1.0)
17
+ base64
18
+ bigdecimal
19
+ concurrent-ruby (~> 1.0, >= 1.3.1)
20
+ connection_pool (>= 2.2.5)
21
+ drb
22
+ i18n (>= 1.6, < 2)
23
+ json
24
+ logger (>= 1.4.2)
25
+ minitest (>= 5.1)
26
+ securerandom (>= 0.3)
27
+ tzinfo (~> 2.0, >= 2.0.5)
28
+ uri (>= 0.13.1)
29
+ base64 (0.3.0)
30
+ bigdecimal (3.3.1)
31
+ concurrent-ruby (1.3.5)
32
+ connection_pool (2.5.4)
33
+ diff-lcs (1.6.2)
34
+ drb (2.2.3)
35
+ gemika (1.0.0)
36
+ i18n (1.14.7)
37
+ concurrent-ruby (~> 1.0)
38
+ json (2.15.1)
39
+ logger (1.7.0)
40
+ minitest (5.26.0)
41
+ pg (1.6.2)
42
+ pg (1.6.2-aarch64-linux)
43
+ pg (1.6.2-aarch64-linux-musl)
44
+ pg (1.6.2-arm64-darwin)
45
+ pg (1.6.2-x86_64-darwin)
46
+ pg (1.6.2-x86_64-linux)
47
+ pg (1.6.2-x86_64-linux-musl)
48
+ rake (13.3.0)
49
+ rspec (3.13.2)
50
+ rspec-core (~> 3.13.0)
51
+ rspec-expectations (~> 3.13.0)
52
+ rspec-mocks (~> 3.13.0)
53
+ rspec-core (3.13.6)
54
+ rspec-support (~> 3.13.0)
55
+ rspec-expectations (3.13.5)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.13.0)
58
+ rspec-mocks (3.13.6)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.13.0)
61
+ rspec-support (3.13.6)
62
+ securerandom (0.4.1)
63
+ timeout (0.4.3)
64
+ tzinfo (2.0.6)
65
+ concurrent-ruby (~> 1.0)
66
+ uri (1.0.4)
67
+
68
+ PLATFORMS
69
+ aarch64-linux
70
+ aarch64-linux-musl
71
+ arm64-darwin
72
+ ruby
73
+ x86_64-darwin
74
+ x86_64-linux
75
+ x86_64-linux-musl
76
+
77
+ DEPENDENCIES
78
+ active_type!
79
+ activerecord (~> 8.1.0)
80
+ gemika
81
+ pg
82
+ rake
83
+ rspec (~> 3.4)
84
+
85
+ BUNDLED WITH
86
+ 2.6.9
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'activerecord', '~>6.1.0'
3
+ gem 'activerecord', '~>8.1.0'
4
4
  gem 'rspec', '~>3.4'
5
5
  gem 'sqlite3'
6
6
  gem 'rake'
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ active_type (2.7.0)
5
+ activerecord (>= 6.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (8.1.0)
11
+ activesupport (= 8.1.0)
12
+ activerecord (8.1.0)
13
+ activemodel (= 8.1.0)
14
+ activesupport (= 8.1.0)
15
+ timeout (>= 0.4.0)
16
+ activesupport (8.1.0)
17
+ base64
18
+ bigdecimal
19
+ concurrent-ruby (~> 1.0, >= 1.3.1)
20
+ connection_pool (>= 2.2.5)
21
+ drb
22
+ i18n (>= 1.6, < 2)
23
+ json
24
+ logger (>= 1.4.2)
25
+ minitest (>= 5.1)
26
+ securerandom (>= 0.3)
27
+ tzinfo (~> 2.0, >= 2.0.5)
28
+ uri (>= 0.13.1)
29
+ base64 (0.3.0)
30
+ bigdecimal (3.3.1)
31
+ concurrent-ruby (1.3.5)
32
+ connection_pool (2.5.4)
33
+ diff-lcs (1.6.2)
34
+ drb (2.2.3)
35
+ gemika (1.0.0)
36
+ i18n (1.14.7)
37
+ concurrent-ruby (~> 1.0)
38
+ json (2.15.1)
39
+ logger (1.7.0)
40
+ minitest (5.26.0)
41
+ rake (13.3.0)
42
+ rspec (3.13.2)
43
+ rspec-core (~> 3.13.0)
44
+ rspec-expectations (~> 3.13.0)
45
+ rspec-mocks (~> 3.13.0)
46
+ rspec-core (3.13.6)
47
+ rspec-support (~> 3.13.0)
48
+ rspec-expectations (3.13.5)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.13.0)
51
+ rspec-mocks (3.13.6)
52
+ diff-lcs (>= 1.2.0, < 2.0)
53
+ rspec-support (~> 3.13.0)
54
+ rspec-support (3.13.6)
55
+ securerandom (0.4.1)
56
+ sqlite3 (2.7.4-aarch64-linux-gnu)
57
+ sqlite3 (2.7.4-aarch64-linux-musl)
58
+ sqlite3 (2.7.4-arm-linux-gnu)
59
+ sqlite3 (2.7.4-arm-linux-musl)
60
+ sqlite3 (2.7.4-arm64-darwin)
61
+ sqlite3 (2.7.4-x86-linux-gnu)
62
+ sqlite3 (2.7.4-x86-linux-musl)
63
+ sqlite3 (2.7.4-x86_64-darwin)
64
+ sqlite3 (2.7.4-x86_64-linux-gnu)
65
+ sqlite3 (2.7.4-x86_64-linux-musl)
66
+ timeout (0.4.3)
67
+ tzinfo (2.0.6)
68
+ concurrent-ruby (~> 1.0)
69
+ uri (1.0.4)
70
+
71
+ PLATFORMS
72
+ aarch64-linux-gnu
73
+ aarch64-linux-musl
74
+ arm-linux-gnu
75
+ arm-linux-musl
76
+ arm64-darwin
77
+ x86-linux-gnu
78
+ x86-linux-musl
79
+ x86_64-darwin
80
+ x86_64-linux-gnu
81
+ x86_64-linux-musl
82
+
83
+ DEPENDENCIES
84
+ active_type!
85
+ activerecord (~> 8.1.0)
86
+ gemika
87
+ rake
88
+ rspec (~> 3.4)
89
+ sqlite3
90
+
91
+ BUNDLED WITH
92
+ 2.5.6
data/README.md CHANGED
@@ -328,7 +328,7 @@ Supported options for `nests_many` / `nests_one` are:
328
328
  nests_many :documents, build_scope: proc { Document }, find_scope: proc { Document }
329
329
  ```
330
330
 
331
- All `...scope` options are evaled in the context of the record on first use, and cached.
331
+ All `...scope` options are evaled in the context of the record on first use, and cached.
332
332
 
333
333
  - `allow_destroy`
334
334
 
@@ -380,7 +380,7 @@ sign_up.is_a?(SignUp) # => true
380
380
  This is basically like [`ActiveRecord#becomes`](http://apidock.com/rails/v4.2.1/ActiveRecord/Persistence/becomes), but with less bugs and more consistent behavior.
381
381
 
382
382
  **Note that `cast` is destructive.** The originally casted record (`user`) and the returned record (`sign_up`)
383
- share internal state (such as attributes). To avoid unexpected behavior, the original record will raise an error when trying to change or persist it. Also, casting of a record that has changes in its loaded associations is prevented, because those changes would be lost.
383
+ share internal state (such as attributes). To avoid unexpected behavior, the original record will raise an error when trying to change or persist it. Also, casting of a record that has changes in its loaded associations is prevented, because those changes would be lost.
384
384
  If you know what you are doing and absolutely want that, you may use the option `force: true` to allow this potentially problematic behaviour, e.g. `sign_up = ActiveType.cast(user, SignUp, force: true)`
385
385
 
386
386
 
@@ -434,14 +434,14 @@ Now, if you load `credentials`, you will automatically receive records of type `
434
434
  Supported Rails versions
435
435
  ------------------------
436
436
 
437
- ActiveType is tested against ActiveRecord 6.1, 7.1, 7.2, 8.0.
437
+ ActiveType is tested against ActiveRecord 7.1, 7.2, 8.0, 8.1.
438
438
 
439
439
  Later versions might work, earlier will not.
440
440
 
441
441
  Supported Ruby versions
442
442
  ------------------------
443
443
 
444
- ActiveType is tested against Ruby 2.7+.
444
+ ActiveType is tested against Ruby 3.1+.
445
445
 
446
446
 
447
447
  Installation
@@ -478,5 +478,3 @@ Credits
478
478
  Tobias Kraze from [makandra](http://makandra.com/)
479
479
 
480
480
  Henning Koch from [makandra](http://makandra.com/)
481
-
482
-
@@ -13,12 +13,8 @@ module ActiveType
13
13
  new_scope = nil
14
14
  end
15
15
  original_options = existing_association.options
16
- if ActiveRecord::VERSION::MAJOR > 3
17
- new_scope ||= existing_association.scope
18
- public_send(existing_association.macro, association_name, new_scope, **original_options.merge(new_options))
19
- else
20
- public_send(existing_association.macro, association_name, **original_options.merge(new_options))
21
- end
16
+ new_scope ||= existing_association.scope
17
+ public_send(existing_association.macro, association_name, new_scope, **original_options.merge(new_options))
22
18
  else
23
19
  raise ArgumentError, "unrecognized association `#{association_name}`"
24
20
  end
@@ -0,0 +1,62 @@
1
+ module ActiveType
2
+ module Marshalling
3
+ # With 7.1 rails defines its own marshal_dump and marshal_load methods,
4
+ # which selectively only dump and load the record´s attributes and some more stuff, but not our @virtual_attributes.
5
+ # Whether these new methods are actually used, depends on ActiveRecord::Marshalling.format_version
6
+ # For format_version = 6.1 active record uses the default ruby implementation for dumping and loading.
7
+ # For format_version = 7.1 active record uses a custom implementation, which we need to override.
8
+ #
9
+ # format_version can also be dynamically changed during runtime, on change we need to define or undefine our marshal_dump dynamically, because:
10
+ # * We cannot check the format_version at runtime within marshal_dump or marshal_load,
11
+ # as we can´t just super to the default for the wrong version, because there is no method to super to.
12
+ # (The default implementation is a ruby internal, not a real method.)
13
+ # * We cannot override the methods at load time only when format version is 7.1,
14
+ # because format version usually gets set after our initialisation and could change at any time.
15
+ #
16
+ # Two facts about ruby also help us with that (also see https://ruby-doc.org/core-2.6.8/Marshal.html):
17
+ # * A custom marshal_load is only used, when marshal_dump is also defined. So we can keep marshal_dump always defined.
18
+ # (If either is missing, ruby will use _dump and _load)
19
+ # * If a serialized object is dumped using _dump it will be loaded using _load, never marshal_load, so a record
20
+ # serialized with format_version = 6.1 using _dump, will always load using _load, ignoring whether marshal_load is defined or not.
21
+ # This ensures objects will always be deserialized with the method they were serialized with. We don´t need to worry about that.
22
+
23
+ class << self
24
+ attr_reader :format_version
25
+
26
+ def format_version=(version)
27
+ case version
28
+ when 6.1
29
+ Methods.remove_method(:marshal_dump) if Methods.method_defined?(:marshal_dump)
30
+ when 7.1
31
+ Methods.alias_method(:marshal_dump, :_marshal_dump_7_1)
32
+ else
33
+ raise ArgumentError, "Unknown marshalling format: #{version.inspect}"
34
+ end
35
+ @format_version = version
36
+ end
37
+ end
38
+
39
+ module ActiveRecordMarshallingExtension
40
+ def format_version=(version)
41
+ ActiveType::Marshalling.format_version = version
42
+ super(version)
43
+ end
44
+ end
45
+
46
+ module Methods
47
+ def _marshal_dump_7_1
48
+ [super, @virtual_attributes]
49
+ end
50
+
51
+ def marshal_load(state)
52
+ super_attributes, @virtual_attributes = state
53
+ super(super_attributes)
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+ ActiveRecord::Marshalling.singleton_class.prepend(ActiveType::Marshalling::ActiveRecordMarshallingExtension)
61
+ # Set ActiveType´s format_version to ActiveRecord´s, in case ActiveRecord uses the default value, which is set before we are loaded.
62
+ ActiveType::Marshalling.format_version = ActiveRecord::Marshalling.format_version
@@ -17,14 +17,7 @@ module ActiveType
17
17
  @reject_if = options.delete(:reject_if)
18
18
  @options = options.dup
19
19
 
20
- @index_errors = case
21
- when ActiveRecord::VERSION::MAJOR < 5
22
- @options[:index_errors]
23
- when ActiveRecord::VERSION::MAJOR < 7
24
- @options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors
25
- else
26
- @options[:index_errors] || ActiveRecord.index_nested_attribute_errors
27
- end
20
+ @index_errors = @options[:index_errors] || ActiveRecord.index_nested_attribute_errors
28
21
  end
29
22
 
30
23
  def assign_attributes(parent, attributes)
@@ -130,17 +123,9 @@ module ActiveType
130
123
  end
131
124
 
132
125
  def add_errors_to_parent(parent, child, index)
133
- if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.1")
134
- child.errors.each do |error|
135
- attribute = translate_error_attribute(error.attribute, index)
136
- parent.errors.add(attribute, error.message)
137
- end
138
- else
139
- child.errors.each do |attribute, message|
140
- attribute = translate_error_attribute(attribute, index)
141
- parent.errors.add(attribute, message)
142
- parent.errors[attribute].uniq!
143
- end
126
+ child.errors.each do |error|
127
+ attribute = translate_error_attribute(error.attribute, index)
128
+ parent.errors.add(attribute, error.message)
144
129
  end
145
130
  end
146
131
 
@@ -1,201 +1,115 @@
1
1
  module ActiveType
2
+ module NoTable
2
3
 
3
- if ActiveRecord::VERSION::MAJOR < 5
4
+ extend ActiveSupport::Concern
4
5
 
5
- module NoTable
6
-
7
- extend ActiveSupport::Concern
8
-
9
- module ClassMethods
10
-
11
- def column_types
12
- {}
13
- end
14
-
15
- def columns
16
- []
17
- end
18
-
19
- def primary_key
20
- nil
21
- end
22
-
23
- def destroy(*)
24
- new
25
- end
26
-
27
- def destroy_all(*)
28
- []
29
- end
30
-
31
- def find_by_sql(*)
32
- []
33
- end
6
+ class DummySchemaCache
34
7
 
8
+ def columns_hash(table_name)
9
+ {}
35
10
  end
36
11
 
37
- def id
38
- nil
12
+ def columns_hash?(table_name)
13
+ return false
39
14
  end
40
15
 
41
- def attribute_names
42
- []
16
+ def data_source_exists?(table_name)
17
+ false
43
18
  end
44
19
 
45
- def transaction(&block)
46
- @_current_transaction_records ||= []
47
- yield
20
+ def clear_data_source_cache!(table_name)
48
21
  end
49
22
 
50
- def destroy
51
- @destroyed = true
52
- freeze
53
- end
23
+ end
54
24
 
55
- def reload
56
- self
25
+ class DummyPool < ActiveRecord::ConnectionAdapters::NullPool
26
+ def with_pool_transaction_isolation_level(*_args)
27
+ yield
57
28
  end
29
+ end
58
30
 
31
+ class DummyConnection < ActiveRecord::ConnectionAdapters::AbstractAdapter
59
32
 
60
- private
33
+ attr_reader :schema_cache
61
34
 
62
- def create(*)
63
- true
35
+ def initialize(*)
36
+ super
37
+ @schema_cache = DummySchemaCache.new
38
+ @pool = DummyPool.new
64
39
  end
65
40
 
66
- def update(*)
67
- true
41
+ def self.quote_column_name(column_name)
42
+ column_name.to_s
68
43
  end
69
44
 
70
- if ActiveRecord::Base.private_method_defined?(:create_record)
71
- def create_record(*)
72
- true
73
- end
74
-
75
- def update_record(*)
76
- true
77
- end
78
- else
79
- def _create_record(*)
80
- @new_record = false
81
- true
82
- end
83
-
84
- def _update_record(*)
85
- true
86
- end
45
+ def pool
46
+ @pool
87
47
  end
88
48
 
89
49
  end
90
50
 
91
- else
92
-
93
- # Rails 5+
94
-
95
- module NoTable
96
-
97
- extend ActiveSupport::Concern
98
-
99
- class DummySchemaCache
100
-
101
- def columns_hash(table_name)
102
- {}
103
- end
104
-
105
- def columns_hash?(table_name)
106
- return false
107
- end
108
-
109
- def data_source_exists?(table_name)
110
- false
111
- end
112
-
113
- def clear_data_source_cache!(table_name)
114
- end
51
+ module ClassMethods
115
52
 
53
+ def connection
54
+ @connection ||= DummyConnection.new(nil)
116
55
  end
117
56
 
118
- class DummyConnection < ActiveRecord::ConnectionAdapters::AbstractAdapter
119
-
120
- attr_reader :schema_cache
121
-
122
- def initialize(*)
123
- super
124
- @schema_cache = DummySchemaCache.new
125
- end
126
-
127
- def self.quote_column_name(column_name)
128
- column_name.to_s
129
- end
130
-
57
+ def with_connection(**)
58
+ yield(connection)
131
59
  end
132
60
 
133
- module ClassMethods
134
-
135
- def connection
136
- @connection ||= DummyConnection.new(nil)
137
- end
138
-
139
- def with_connection(**)
140
- yield(connection)
141
- end
142
-
143
- def destroy(*)
144
- new
145
- end
146
-
147
- def destroy_all(*)
148
- []
149
- end
150
-
151
- def find_by_sql(*)
152
- []
153
- end
61
+ def destroy(*)
62
+ new
63
+ end
154
64
 
155
- def _query_by_sql(*)
156
- []
157
- end
65
+ def destroy_all(*)
66
+ []
67
+ end
158
68
 
159
- def cached_find_by(*)
160
- nil
161
- end
69
+ def find_by_sql(*)
70
+ []
71
+ end
162
72
 
163
- def schema_cache
164
- DummySchemaCache.new
165
- end
73
+ def _query_by_sql(*)
74
+ []
166
75
  end
167
76
 
168
- def destroy
169
- @destroyed = true
170
- freeze
77
+ def cached_find_by(*)
78
+ nil
171
79
  end
172
80
 
173
- def reload
174
- self
81
+ def schema_cache
82
+ DummySchemaCache.new
175
83
  end
84
+ end
176
85
 
86
+ def destroy
87
+ @destroyed = true
88
+ freeze
89
+ end
177
90
 
178
- private
91
+ def reload
92
+ self
93
+ end
179
94
 
180
- def create(*)
181
- true
182
- end
95
+ private
183
96
 
184
- def update(*)
185
- true
186
- end
97
+ def create(*)
98
+ true
99
+ end
187
100
 
188
- def _create_record(*)
189
- @new_record = false
190
- true
191
- end
101
+ def update(*)
102
+ true
103
+ end
192
104
 
193
- def _update_record(*)
194
- true
195
- end
105
+ def _create_record(*)
106
+ @new_record = false
107
+ true
108
+ end
196
109
 
110
+ def _update_record(*)
111
+ true
197
112
  end
198
113
 
199
114
  end
200
-
201
115
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_type/no_table'
2
2
  require 'active_type/virtual_attributes'
3
3
  require 'active_type/nested_attributes'
4
+ require 'active_type/marshalling'
4
5
 
5
6
  module ActiveType
6
7
 
@@ -9,6 +10,7 @@ module ActiveType
9
10
  include NoTable
10
11
  include VirtualAttributes
11
12
  include NestedAttributes
13
+ include Marshalling::Methods
12
14
 
13
15
  end
14
16
 
@@ -2,6 +2,7 @@ require 'active_type/virtual_attributes'
2
2
  require 'active_type/record_extension'
3
3
  require 'active_type/nested_attributes'
4
4
  require 'active_type/change_association'
5
+ require 'active_type/marshalling'
5
6
 
6
7
  module ActiveType
7
8
 
@@ -13,6 +14,7 @@ module ActiveType
13
14
  include NestedAttributes
14
15
  include RecordExtension
15
16
  include ChangeAssociation
17
+ include Marshalling::Methods
16
18
 
17
19
  end
18
20
 
@@ -18,11 +18,7 @@ module ActiveType
18
18
  unless options[:foreign_key] || options[:as]
19
19
  options = options.merge(foreign_key: extended_record_base_class.name.foreign_key)
20
20
  end
21
- if ActiveRecord::VERSION::MAJOR > 3
22
- [options, scope]
23
- else
24
- [options]
25
- end
21
+ [options, scope]
26
22
  end
27
23
 
28
24
  module ClassMethods
@@ -66,7 +62,7 @@ module ActiveType
66
62
 
67
63
  def has_many(name, scope=nil, *args, &extension)
68
64
  new_args, new_scope = Inheritance.add_foreign_key_option(extended_record_base_class, scope, *args)
69
- if ActiveRecord::VERSION::MAJOR <= 3 || new_scope.nil?
65
+ if new_scope.nil?
70
66
  super(name, **new_args, &extension)
71
67
  else
72
68
  super(name, new_scope, **new_args, &extension)
@@ -75,7 +71,7 @@ module ActiveType
75
71
 
76
72
  def has_one(name, scope=nil, *args, &extension)
77
73
  new_args, new_scope = Inheritance.add_foreign_key_option(extended_record_base_class, scope, *args)
78
- if ActiveRecord::VERSION::MAJOR <= 3 || new_scope.nil?
74
+ if new_scope.nil?
79
75
  super(name, **new_args, &extension)
80
76
  else
81
77
  super(name, new_scope, **new_args, &extension)
@@ -84,79 +80,48 @@ module ActiveType
84
80
 
85
81
  private
86
82
 
87
- if ActiveRecord::VERSION::MAJOR < 5
88
-
89
- def find_sti_class(type_name)
90
- sti_class = super
91
-
92
- # Consider this class hierarchy
93
- # class Parent < ActiveRecord::Base; end
94
- # class Child < Parent; end
95
- # class ExtendedParent < ActiveType::Record[Parent]; end
96
- # class ExtendedChild < ActiveType::Record[Child]; end
97
- if self < sti_class
98
- # i.e. ExtendendChild.find(child.id)
99
- # => self = ExtendedChild; sti_class = Child
100
- # instantiate as ExtendedChild
101
- self
102
- elsif sti_class < extended_record_base_class
103
- # i.e. ExtendedParent.find(child.id)
104
- # => sti_class = Child; self = ExtendedParent; extended_record_base_class = Parent
105
- # There is no really good solution here, since we cannot instantiate as both ExtendedParent
106
- # and Child. We opt to instantiate as ExtendedParent, since the other option can be
107
- # achieved by using Parent.find(child.id)
108
- self
83
+ # Rails 5 find_sti_class does a sanity check for proper inheritance that fails for
84
+ # our usecase
85
+ # copied from activerecord/lib/active_record/inheritance.rb
86
+ def find_sti_class(type_name)
87
+ type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
88
+ subclass = begin
89
+ if store_full_sti_class
90
+ type_name.constantize
109
91
  else
110
- sti_class
92
+ compute_type(type_name)
111
93
  end
94
+ rescue NameError
95
+ raise ActiveRecord::SubclassNotFound,
96
+ "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
97
+ "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
98
+ "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
99
+ "or overwrite #{name}.inheritance_column to use another column for that information."
112
100
  end
113
-
114
- else
115
-
116
- # Rails 5 find_sti_class does a sanity check for proper inheritance that fails for
117
- # our usecase
118
- # copied from activerecord/lib/active_record/inheritance.rb
119
- def find_sti_class(type_name)
120
- type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
121
- subclass = begin
122
- if store_full_sti_class
123
- type_name.constantize
124
- else
125
- compute_type(type_name)
126
- end
127
- rescue NameError
128
- raise ActiveRecord::SubclassNotFound,
129
- "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
130
- "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
131
- "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
132
- "or overwrite #{name}.inheritance_column to use another column for that information."
133
- end
134
- #### our code starts here
135
- # Consider this class hierarchy
136
- # class Parent < ActiveRecord::Base; end
137
- # class Child < Parent; end
138
- # class ExtendedParent < ActiveType::Record[Parent]; end
139
- # class ExtendedChild < ActiveType::Record[Child]; end
140
- if self < subclass
141
- # i.e. ExtendendChild.find(child.id)
142
- # => self = ExtendedChild; subclass = Child
143
- # instantiate as ExtendedChild
144
- subclass = self
145
- elsif subclass < extended_record_base_class
146
- # i.e. ExtendedParent.find(child.id)
147
- # => subclass = Child; self = ExtendedParent; extended_record_base_class = Parent
148
- # There is no really good solution here, since we cannot instantiate as both ExtendedParent
149
- # and Child. We opt to instantiate as ExtendedParent, since the other option can be
150
- # achieved by using Parent.find(child.id)
151
- subclass = self
152
- end
153
- #### our code ends here
154
- unless subclass == self || descendants.include?(subclass)
155
- raise ActiveRecord::SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
156
- end
157
- subclass
101
+ #### our code starts here
102
+ # Consider this class hierarchy
103
+ # class Parent < ActiveRecord::Base; end
104
+ # class Child < Parent; end
105
+ # class ExtendedParent < ActiveType::Record[Parent]; end
106
+ # class ExtendedChild < ActiveType::Record[Child]; end
107
+ if self < subclass
108
+ # i.e. ExtendendChild.find(child.id)
109
+ # => self = ExtendedChild; subclass = Child
110
+ # instantiate as ExtendedChild
111
+ subclass = self
112
+ elsif subclass < extended_record_base_class
113
+ # i.e. ExtendedParent.find(child.id)
114
+ # => subclass = Child; self = ExtendedParent; extended_record_base_class = Parent
115
+ # There is no really good solution here, since we cannot instantiate as both ExtendedParent
116
+ # and Child. We opt to instantiate as ExtendedParent, since the other option can be
117
+ # achieved by using Parent.find(child.id)
118
+ subclass = self
158
119
  end
159
-
120
+ #### our code ends here
121
+ unless subclass == self || descendants.include?(subclass)
122
+ raise ActiveRecord::SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
123
+ end
124
+ subclass
160
125
  end
161
126
 
162
127
  end
@@ -2,13 +2,7 @@ module ActiveType
2
2
  class TypeCaster
3
3
 
4
4
  def self.get(type)
5
- native_caster = if ActiveRecord::VERSION::STRING < '4.2'
6
- NativeCasters::DelegateToColumn.new(type)
7
- elsif ActiveRecord::VERSION::STRING < '5'
8
- NativeCasters::DelegateToRails4Type.new(type)
9
- else
10
- NativeCasters::DelegateToRails5Type.new(type)
11
- end
5
+ native_caster = NativeCasters::DelegateToRailsType.new(type)
12
6
  new(type, native_caster)
13
7
  end
14
8
 
@@ -104,7 +98,7 @@ module ActiveType
104
98
 
105
99
  # Adapter for Rails 5+.
106
100
  # In these versions, casting logic lives in subclasses of ActiveRecord::Type::Value
107
- class DelegateToRails5Type
101
+ class DelegateToRailsType
108
102
 
109
103
  def initialize(type)
110
104
  @active_record_type = lookup(type)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveType
2
- VERSION = '2.6.4'
4
+ VERSION = '2.7.0'
3
5
  end
@@ -189,34 +189,24 @@ module ActiveType
189
189
  read_existing_virtual_attribute(name) { super }
190
190
  end
191
191
 
192
- if ActiveRecord::VERSION::STRING >= '4.2.0'
193
- def _read_attribute(name)
194
- read_existing_virtual_attribute(name) { super }
195
- end
192
+ def _read_attribute(name)
193
+ read_existing_virtual_attribute(name) { super }
196
194
  end
197
195
 
198
- if ActiveRecord::VERSION::STRING < '4.2.0' || ActiveRecord::VERSION::STRING >= '6.1.0'
199
- # in 6.1, read_attribute does not call _read_attribute
200
- def read_attribute(name)
201
- read_existing_virtual_attribute(name) { super }
202
- end
196
+ def read_attribute(name)
197
+ read_existing_virtual_attribute(name) { super }
203
198
  end
204
199
 
205
200
  def []=(name, value)
206
201
  write_existing_virtual_attribute(name, value) { super }
207
202
  end
208
203
 
209
- if ActiveRecord::VERSION::STRING >= '5.2.0'
210
- def _write_attribute(name, value)
211
- write_existing_virtual_attribute(name, value) { super }
212
- end
204
+ def _write_attribute(name, value)
205
+ write_existing_virtual_attribute(name, value) { super }
213
206
  end
214
207
 
215
- if ActiveRecord::VERSION::STRING < '5.2.0' || ActiveRecord::VERSION::STRING >= '6.1.0'
216
- # in 6.1, write_attribute does not call _write_attribute
217
- def write_attribute(name, value)
218
- write_existing_virtual_attribute(name, value) { super }
219
- end
208
+ def write_attribute(name, value)
209
+ write_existing_virtual_attribute(name, value) { super }
220
210
  end
221
211
 
222
212
  def attributes
@@ -252,14 +242,12 @@ module ActiveType
252
242
  end
253
243
  end
254
244
 
255
- if ActiveRecord::VERSION::MAJOR >= 4
256
- def changes_applied
257
- super
245
+ def changes_applied
246
+ super
258
247
 
259
- virtual_attributes.each do |attr, _|
260
- value = read_virtual_attribute(attr)
261
- virtual_attributes_were[attr] = value.duplicable? ? value.clone : value
262
- end
248
+ virtual_attributes.each do |attr, _|
249
+ value = read_virtual_attribute(attr)
250
+ virtual_attributes_were[attr] = value.duplicable? ? value.clone : value
263
251
  end
264
252
  end
265
253
 
data/lib/active_type.rb CHANGED
@@ -4,13 +4,6 @@ require 'active_type/version'
4
4
 
5
5
  require 'active_record'
6
6
 
7
- if ActiveRecord::VERSION::STRING == '4.2.0'
8
- raise(<<-MESSAGE.strip_heredoc)
9
- ActiveType is not compatible with ActiveRecord 4.2.0. Please upgrade to 4.2.1
10
- For details see https://github.com/makandra/active_type/issues/31
11
- MESSAGE
12
- end
13
-
14
7
  module ActiveType
15
8
  extend ActiveSupport::Autoload
16
9
 
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.4
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Kraze
8
8
  - Henning Koch
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2025-09-11 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
@@ -65,12 +64,6 @@ files:
65
64
  - ".ruby-version"
66
65
  - CHANGELOG.md
67
66
  - Gemfile
68
- - Gemfile.6.1.pg
69
- - Gemfile.6.1.pg.lock
70
- - Gemfile.6.1.sqlite3
71
- - Gemfile.6.1.sqlite3.lock
72
- - Gemfile.7.1.pg
73
- - Gemfile.7.1.pg.lock
74
67
  - Gemfile.7.1.sqlite3
75
68
  - Gemfile.7.1.sqlite3.lock
76
69
  - Gemfile.7.2.mysql2
@@ -81,6 +74,10 @@ files:
81
74
  - Gemfile.7.2.sqlite3.lock
82
75
  - Gemfile.8.0.sqlite3
83
76
  - Gemfile.8.0.sqlite3.lock
77
+ - Gemfile.8.1.pg
78
+ - Gemfile.8.1.pg.lock
79
+ - Gemfile.8.1.sqlite3
80
+ - Gemfile.8.1.sqlite3.lock
84
81
  - Gemfile.lock
85
82
  - LICENSE
86
83
  - README.md
@@ -88,6 +85,7 @@ files:
88
85
  - active_type.gemspec
89
86
  - lib/active_type.rb
90
87
  - lib/active_type/change_association.rb
88
+ - lib/active_type/marshalling.rb
91
89
  - lib/active_type/mutation_after_cast_error.rb
92
90
  - lib/active_type/nested_attributes.rb
93
91
  - lib/active_type/nested_attributes/association.rb
@@ -119,7 +117,6 @@ metadata:
119
117
  bug_tracker_uri: https://github.com/makandra/active_type/issues
120
118
  changelog_uri: https://github.com/makandra/active_type/blob/master/CHANGELOG.md
121
119
  rubygems_mfa_required: 'true'
122
- post_install_message:
123
120
  rdoc_options: []
124
121
  require_paths:
125
122
  - lib
@@ -134,8 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
131
  - !ruby/object:Gem::Version
135
132
  version: '0'
136
133
  requirements: []
137
- rubygems_version: 3.4.10
138
- signing_key:
134
+ rubygems_version: 3.6.7
139
135
  specification_version: 4
140
136
  summary: Make any Ruby object quack like ActiveRecord
141
137
  test_files: []
data/Gemfile.6.1.pg.lock DELETED
@@ -1,59 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- active_type (2.6.3)
5
- activerecord (>= 6.1)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (6.1.3)
11
- activesupport (= 6.1.3)
12
- activerecord (6.1.3)
13
- activemodel (= 6.1.3)
14
- activesupport (= 6.1.3)
15
- activesupport (6.1.3)
16
- concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (>= 1.6, < 2)
18
- minitest (>= 5.1)
19
- tzinfo (~> 2.0)
20
- zeitwerk (~> 2.3)
21
- concurrent-ruby (1.1.8)
22
- diff-lcs (1.4.4)
23
- gemika (0.6.0)
24
- i18n (1.8.9)
25
- concurrent-ruby (~> 1.0)
26
- minitest (5.14.4)
27
- pg (1.2.3)
28
- rake (13.0.3)
29
- rspec (3.10.0)
30
- rspec-core (~> 3.10.0)
31
- rspec-expectations (~> 3.10.0)
32
- rspec-mocks (~> 3.10.0)
33
- rspec-core (3.10.1)
34
- rspec-support (~> 3.10.0)
35
- rspec-expectations (3.10.1)
36
- diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.10.0)
38
- rspec-mocks (3.10.2)
39
- diff-lcs (>= 1.2.0, < 2.0)
40
- rspec-support (~> 3.10.0)
41
- rspec-support (3.10.2)
42
- tzinfo (2.0.4)
43
- concurrent-ruby (~> 1.0)
44
- zeitwerk (2.4.2)
45
-
46
- PLATFORMS
47
- ruby
48
- x86_64-linux
49
-
50
- DEPENDENCIES
51
- active_type!
52
- activerecord (~> 6.1.0)
53
- gemika
54
- pg
55
- rake
56
- rspec (~> 3.4)
57
-
58
- BUNDLED WITH
59
- 2.2.27
@@ -1,59 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- active_type (2.6.3)
5
- activerecord (>= 6.1)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (6.1.3)
11
- activesupport (= 6.1.3)
12
- activerecord (6.1.3)
13
- activemodel (= 6.1.3)
14
- activesupport (= 6.1.3)
15
- activesupport (6.1.3)
16
- concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (>= 1.6, < 2)
18
- minitest (>= 5.1)
19
- tzinfo (~> 2.0)
20
- zeitwerk (~> 2.3)
21
- concurrent-ruby (1.1.8)
22
- diff-lcs (1.4.4)
23
- gemika (0.6.0)
24
- i18n (1.8.9)
25
- concurrent-ruby (~> 1.0)
26
- minitest (5.14.4)
27
- rake (13.0.3)
28
- rspec (3.10.0)
29
- rspec-core (~> 3.10.0)
30
- rspec-expectations (~> 3.10.0)
31
- rspec-mocks (~> 3.10.0)
32
- rspec-core (3.10.1)
33
- rspec-support (~> 3.10.0)
34
- rspec-expectations (3.10.1)
35
- diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.10.0)
37
- rspec-mocks (3.10.2)
38
- diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.10.0)
40
- rspec-support (3.10.2)
41
- sqlite3 (1.4.2)
42
- tzinfo (2.0.4)
43
- concurrent-ruby (~> 1.0)
44
- zeitwerk (2.4.2)
45
-
46
- PLATFORMS
47
- ruby
48
- x86_64-linux
49
-
50
- DEPENDENCIES
51
- active_type!
52
- activerecord (~> 6.1.0)
53
- gemika
54
- rake
55
- rspec (~> 3.4)
56
- sqlite3
57
-
58
- BUNDLED WITH
59
- 2.2.27
data/Gemfile.7.1.pg DELETED
@@ -1,9 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'activerecord', '~>7.1.0'
4
- gem 'rspec', '~>3.4'
5
- gem 'pg'
6
- gem 'rake'
7
- gem 'gemika'
8
-
9
- gem 'active_type', :path => '.'
data/Gemfile.7.1.pg.lock DELETED
@@ -1,68 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- active_type (2.6.3)
5
- activerecord (>= 6.1)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (7.1.3.4)
11
- activesupport (= 7.1.3.4)
12
- activerecord (7.1.3.4)
13
- activemodel (= 7.1.3.4)
14
- activesupport (= 7.1.3.4)
15
- timeout (>= 0.4.0)
16
- activesupport (7.1.3.4)
17
- base64
18
- bigdecimal
19
- concurrent-ruby (~> 1.0, >= 1.0.2)
20
- connection_pool (>= 2.2.5)
21
- drb
22
- i18n (>= 1.6, < 2)
23
- minitest (>= 5.1)
24
- mutex_m
25
- tzinfo (~> 2.0)
26
- base64 (0.2.0)
27
- bigdecimal (3.1.8)
28
- concurrent-ruby (1.3.4)
29
- connection_pool (2.4.1)
30
- diff-lcs (1.5.1)
31
- drb (2.2.1)
32
- gemika (0.8.3)
33
- i18n (1.14.5)
34
- concurrent-ruby (~> 1.0)
35
- minitest (5.24.1)
36
- mutex_m (0.2.0)
37
- pg (1.5.7)
38
- rake (13.2.1)
39
- rspec (3.13.0)
40
- rspec-core (~> 3.13.0)
41
- rspec-expectations (~> 3.13.0)
42
- rspec-mocks (~> 3.13.0)
43
- rspec-core (3.13.0)
44
- rspec-support (~> 3.13.0)
45
- rspec-expectations (3.13.1)
46
- diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.13.0)
48
- rspec-mocks (3.13.1)
49
- diff-lcs (>= 1.2.0, < 2.0)
50
- rspec-support (~> 3.13.0)
51
- rspec-support (3.13.1)
52
- timeout (0.4.1)
53
- tzinfo (2.0.6)
54
- concurrent-ruby (~> 1.0)
55
-
56
- PLATFORMS
57
- ruby
58
-
59
- DEPENDENCIES
60
- active_type!
61
- activerecord (~> 7.1.0)
62
- gemika
63
- pg
64
- rake
65
- rspec (~> 3.4)
66
-
67
- BUNDLED WITH
68
- 2.5.6