activerecord-null 0.1.1 → 0.1.3

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: bfe02235c54d325ce319a9c7cf6123c71e3aab539f21788262671f445a344688
4
- data.tar.gz: b125dada1c0fce080fd37f3a3ccf9525bd61b427c4027c0b3095fcd1ddd85bb7
3
+ metadata.gz: 61c6b213e7c4c8f5cbeab18700a2eebc46803592fb34b3677ed93da0a6c49c92
4
+ data.tar.gz: 698f74dbdf03af5dbdc7e35111f20a478363c832028258c77cc14fdf0061b8b0
5
5
  SHA512:
6
- metadata.gz: 0f61caa026a58fe1faee75009734df5e283d62077093c472b191f25497098e8afca8216a33923f70650e2f022e41ec0d6ca29c8273af80ec0b1e205d6913ff69
7
- data.tar.gz: 73b85e766af51fe0dfd7192d80181100584faa81ecf1a6e76b3d08bb06b7738c54d662976385480044b4119f41ac6218950caf07fbc66f249c086a49001cf4e5
6
+ metadata.gz: 3e8fd9f3d1c8c130a997e3c66c6560b82e18b2ff782a2772832de7e4344abb59f0a6ef0efcaae67cb2a47dd221076b1113be2a0f520bc0c267a6ecb137c3b7eb
7
+ data.tar.gz: 9848bd89df1f1cb2ded9dcecd27f478aacbac6ed1586f56ecd7b17446b3755bceec6fbef8b0858b58be7996da11617c1d2f056517c0a55a03aff26a79ee483e5
data/CHANGELOG.md CHANGED
@@ -5,16 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [0.1.1] - 2024-10-25
8
+ ## [0.1.3] - 2025-11-18
9
9
 
10
- ### Added
10
+ ### Changed
11
11
 
12
- - `null?` method to both parent class objects and null objects
13
- - Null objects now have default nil values for attributes of the mimic model class
14
- - `Null()` method can now accept a hash of attribute names and values to assign to the null object
12
+ - Use git trailers to track changelog entries. (d296851)
13
+ - Implement [] method to access attributes with string/symbol keys (1dc4f95)
15
14
 
16
- ## [0.1.0] - 2024-10-23
15
+ ### Removed
17
16
 
18
- ### Added
17
+ - CodeClimate access on CI runs. (2dbf5bc)
19
18
 
20
- - Initial release
19
+ ## [0.1.3] - 2025-11-18
20
+
21
+ ### Changed
22
+
23
+ - Use git trailers to track changelog entries. (d296851)
24
+ - Implement [] method to access attributes with string/symbol keys (1dc4f95)
25
+
26
+ ### Removed
27
+
28
+ - CodeClimate access on CI runs. (2dbf5bc)
data/README.md CHANGED
@@ -48,6 +48,26 @@ It will even work with associations.
48
48
  User.null.posts # => []
49
49
  ```
50
50
 
51
+ By default, the null object will have the same attributes as the original model and will return `nil` for all attributes.
52
+
53
+ You can override this by passing a hash to the `Null` method where the key is an array of attributes and the value is the value to return for the attribute.
54
+
55
+ ```ruby
56
+ class User < ApplicationRecord
57
+ Null([:name, :team_name] => "Unknown") do
58
+ def other_attribute = "Other"
59
+ end
60
+ end
61
+ ```
62
+
63
+ You may also pass a callable to the hash which will be used to determine the value for the attribute.
64
+
65
+ ```ruby
66
+ class User < ApplicationRecord
67
+ Null([:name, :team_name] => -> { "Unknown" })
68
+ end
69
+ ```
70
+
51
71
  ## Development
52
72
 
53
73
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -3,7 +3,9 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "minitest/test_task"
5
5
 
6
- Minitest::TestTask.create
6
+ Minitest::TestTask.create do |t|
7
+ t.test_prelude = 'require "test_helper"'
8
+ end
7
9
 
8
10
  task default: :test
9
11
 
@@ -11,4 +13,5 @@ require "reissue/gem"
11
13
 
12
14
  Reissue::Task.create :reissue do |task|
13
15
  task.version_file = "lib/activerecord/null/version.rb"
16
+ task.fragment = :git
14
17
  end
@@ -35,7 +35,13 @@ module ActiveRecord
35
35
 
36
36
  attr_reader :id
37
37
 
38
- def [](*)
38
+ def [](key)
39
+ normalized_key = key.to_sym
40
+ association_names = mimic_model_class.reflect_on_all_associations.map(&:name)
41
+
42
+ return nil if association_names.include?(normalized_key)
43
+
44
+ respond_to?(normalized_key) ? send(normalized_key) : nil
39
45
  end
40
46
 
41
47
  def is_a?(klass)
@@ -54,6 +60,8 @@ module ActiveRecord
54
60
 
55
61
  def persisted? = false
56
62
 
63
+ def _read_attribute(_) = nil
64
+
57
65
  def method_missing(method, ...)
58
66
  reflections = mimic_model_class.reflect_on_all_associations
59
67
  if (reflection = reflections.find { |r| r.name == method })
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Null
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.3"
6
6
  end
7
7
  end
@@ -40,9 +40,20 @@ module ActiveRecord
40
40
  end
41
41
  null_class = Class.new do
42
42
  include ::ActiveRecord::Null::Mimic
43
+
43
44
  mimics inherit
44
45
 
45
46
  include Singleton
47
+
48
+ class << self
49
+ def method_missing(method, ...)
50
+ mimic_model_class.respond_to?(method) ? mimic_model_class.send(method, ...) : super
51
+ end
52
+
53
+ def respond_to_missing?(method, include_private = false)
54
+ mimic_model_class.respond_to?(method, include_private) || super
55
+ end
56
+ end
46
57
  end
47
58
  null_class.class_eval(&) if block_given?
48
59
 
@@ -35,6 +35,18 @@ class ActiveRecord::TestNull < Minitest::Spec
35
35
  end
36
36
  end
37
37
 
38
+ describe ".has_query_constraints?" do
39
+ it "returns false" do
40
+ expect(User::Null.has_query_constraints?).must_equal false
41
+ end
42
+ end
43
+
44
+ describe ".composite_primary_key?" do
45
+ it "returns false" do
46
+ expect(User::Null.composite_primary_key?).must_equal false
47
+ end
48
+ end
49
+
38
50
  describe "Null" do
39
51
  it "is null" do
40
52
  expect(User.null.null?).must_equal true
@@ -104,6 +116,76 @@ class ActiveRecord::TestNull < Minitest::Spec
104
116
  it "assigns callable values to attributes" do
105
117
  expect(Post.null.description).must_equal "From the callable!"
106
118
  end
119
+
120
+ it "reads attributes and returns nil" do
121
+ expect(Post.null._read_attribute(:description)).must_be_nil
122
+ end
123
+
124
+ it "responds to mimic methods" do
125
+ expect(Post.null.respond_to?(:description)).must_equal true
126
+ end
127
+
128
+ describe "bracket access" do
129
+ describe "with attributes" do
130
+ it "accesses attribute with symbol key" do
131
+ expect(User.null[:name]).must_equal "None"
132
+ end
133
+
134
+ it "accesses attribute with string key" do
135
+ expect(User.null["name"]).must_equal "None"
136
+ end
137
+
138
+ it "returns same value for string and symbol keys" do
139
+ expect(User.null[:team_name]).must_equal User.null["team_name"]
140
+ expect(User.null[:team_name]).must_equal "Unknown"
141
+ end
142
+
143
+ it "returns custom attribute values" do
144
+ expect(User.null[:name]).must_equal "None"
145
+ end
146
+
147
+ it "returns static assigned attribute values" do
148
+ expect(User.null[:team_name]).must_equal "Unknown"
149
+ expect(User.null[:other]).must_equal "Unknown"
150
+ end
151
+
152
+ it "returns callable attribute values" do
153
+ expect(Post.null[:description]).must_equal "From the callable!"
154
+ expect(Post.null["description"]).must_equal "From the callable!"
155
+ end
156
+
157
+ it "returns nil for default attributes" do
158
+ expect(User.null[:id]).must_be_nil
159
+ expect(Post.null[:title]).must_be_nil
160
+ end
161
+ end
162
+
163
+ describe "with associations" do
164
+ it "returns nil for belongs_to association" do
165
+ expect(User.null[:business]).must_be_nil
166
+ expect(Post.null[:user]).must_be_nil
167
+ end
168
+
169
+ it "returns nil for has_many association" do
170
+ expect(User.null[:posts]).must_be_nil
171
+ end
172
+
173
+ it "still allows dot notation for associations" do
174
+ expect(User.null.business).must_be_instance_of Business::Null
175
+ expect(User.null.posts).must_be_kind_of ActiveRecord::Relation
176
+ end
177
+ end
178
+
179
+ describe "with non-existent keys" do
180
+ it "returns nil for unknown symbol key" do
181
+ expect(User.null[:nonexistent]).must_be_nil
182
+ end
183
+
184
+ it "returns nil for unknown string key" do
185
+ expect(User.null["nonexistent"]).must_be_nil
186
+ end
187
+ end
188
+ end
107
189
  end
108
190
 
109
191
  describe "Parent class object" do
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-null
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-10-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activerecord
@@ -49,7 +48,6 @@ metadata:
49
48
  homepage_uri: https://github.com/SOFware/activerecord-null
50
49
  source_code_uri: https://github.com/SOFware/activerecord-null
51
50
  changelog_uri: https://github.com/SOFware/activerecord-null/blob/main/CHANGELOG.md
52
- post_install_message:
53
51
  rdoc_options: []
54
52
  require_paths:
55
53
  - lib
@@ -64,8 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
62
  - !ruby/object:Gem::Version
65
63
  version: '0'
66
64
  requirements: []
67
- rubygems_version: 3.5.9
68
- signing_key:
65
+ rubygems_version: 3.7.2
69
66
  specification_version: 4
70
67
  summary: Null Objects for ActiveRecord
71
68
  test_files: []