null_association 0.0.1 → 1.0.0.pre.rc.1
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 +4 -4
- data/README.md +88 -13
- data/lib/null_association/concern.rb +36 -0
- data/lib/null_association/decorator.rb +29 -0
- data/lib/null_association/railtie.rb +7 -0
- data/lib/null_association/version.rb +1 -1
- data/lib/null_association.rb +8 -2
- metadata +63 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48a3698a82078bbaf946f0f9641a040eeaff9d01cdffc12095682bd92f303b90
|
4
|
+
data.tar.gz: '069daf7962c4033fbf9e75aca18e921e1d7c0333615318fe5d80cf0369068d39'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a86914e281b47ebcc852fcd4b9300bd6d168e58d3a66439aa18bf6787525285ae1c828f2a9f721b2a68b3c93081a4768499be09af2bbfdacd13fe52cc7c1c7bf
|
7
|
+
data.tar.gz: '0914e87d2a2e67f6f441b2ec152a617772128994cac5bf3ae896920fcd4aef4cb0fd956807eedba67b1c285b25fce2180250d30ce19e402040a606ef9e3189f4'
|
data/README.md
CHANGED
@@ -1,31 +1,106 @@
|
|
1
|
-
#
|
1
|
+
# null_association
|
2
2
|
|
3
|
-
|
3
|
+
[](https://github.com/keygen-sh/null_association/actions)
|
4
|
+
[](https://badge.fury.io/rb/null_association)
|
4
5
|
|
5
|
-
|
6
|
+
Use `null_association` to utilize the [null object pattern](https://en.wikipedia.org/wiki/Null_object_pattern)
|
7
|
+
with Active Record associations.
|
8
|
+
|
9
|
+
This gem was extracted from [Keygen](https://keygen.sh).
|
10
|
+
|
11
|
+
Sponsored by:
|
12
|
+
|
13
|
+
<a href="https://keygen.sh?ref=null_association">
|
14
|
+
<div>
|
15
|
+
<img src="https://keygen.sh/images/logo-pill.png" width="200" alt="Keygen">
|
16
|
+
</div>
|
17
|
+
</a>
|
18
|
+
|
19
|
+
_A fair source software licensing and distribution API._
|
6
20
|
|
7
21
|
## Installation
|
8
22
|
|
9
|
-
|
23
|
+
Add this line to your application's `Gemfile`:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'null_association'
|
27
|
+
```
|
10
28
|
|
11
|
-
|
29
|
+
And then execute:
|
12
30
|
|
13
|
-
|
31
|
+
```bash
|
32
|
+
$ bundle
|
33
|
+
```
|
14
34
|
|
15
|
-
|
35
|
+
Or install it yourself as:
|
16
36
|
|
17
|
-
|
37
|
+
```bash
|
38
|
+
$ gem install null_association
|
39
|
+
```
|
18
40
|
|
19
41
|
## Usage
|
20
42
|
|
21
|
-
|
43
|
+
To use a null object, define an optional singular association and use the
|
44
|
+
`null_object:` keyword, which accepts a class, a string, or an instance. When
|
45
|
+
the association is nil, the null object will be returned instead.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class NullPlan
|
49
|
+
include Singleton
|
50
|
+
|
51
|
+
def name = 'Free'
|
52
|
+
def free? = true
|
53
|
+
def pro? = false
|
54
|
+
def ent? = false
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class NullBilling
|
60
|
+
include Singleton
|
61
|
+
|
62
|
+
def subscribed? = true
|
63
|
+
def trialing? = false
|
64
|
+
def canceled? = false
|
65
|
+
end
|
66
|
+
```
|
22
67
|
|
23
|
-
|
68
|
+
```ruby
|
69
|
+
class Account
|
70
|
+
belongs_to :plan, optional: true, null_object: NullPlan.instance
|
71
|
+
has_one :billing, null_object: NullBilling.instance
|
72
|
+
end
|
73
|
+
```
|
24
74
|
|
25
|
-
|
75
|
+
```ruby
|
76
|
+
account = Account.create(plan: nil)
|
26
77
|
|
27
|
-
|
78
|
+
puts account.plan # => #<NullPlan name="Free">
|
79
|
+
puts account.plan.free? # => true
|
80
|
+
puts account.plan.ent? # => false
|
81
|
+
|
82
|
+
account.update(plan: Plan.new(name: 'Ent', ent: true))
|
83
|
+
|
84
|
+
puts account.plan # => #<Plan id=1 name="Ent">
|
85
|
+
puts account.plan.free? # => false
|
86
|
+
puts account.plan.ent? # => true
|
87
|
+
```
|
88
|
+
|
89
|
+
## Supported Rubies
|
90
|
+
|
91
|
+
**`null_association` supports Ruby 3.1 and above.** We encourage you to upgrade
|
92
|
+
if you're on an older version. Ruby 3 provides a lot of great features, like
|
93
|
+
better pattern matching and a new shorthand hash syntax.
|
94
|
+
|
95
|
+
## Is it any good?
|
96
|
+
|
97
|
+
Yes.
|
28
98
|
|
29
99
|
## Contributing
|
30
100
|
|
31
|
-
|
101
|
+
If you have an idea, or have discovered a bug, please open an issue or create a
|
102
|
+
pull request.
|
103
|
+
|
104
|
+
## License
|
105
|
+
|
106
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'decorator'
|
4
|
+
|
5
|
+
module NullAssociation
|
6
|
+
module Concern
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def belongs_to(name, scope = nil, null_object: nil, **options, &extension)
|
11
|
+
return super(name, scope, **options, &extension) if null_object.nil?
|
12
|
+
|
13
|
+
unless options[:optional]
|
14
|
+
raise ArgumentError, 'must be :optional to use :null_object'
|
15
|
+
end
|
16
|
+
|
17
|
+
# generate getter
|
18
|
+
super(name, scope, **options, &extension)
|
19
|
+
|
20
|
+
# decorate getter
|
21
|
+
include Decorator[name, null_object:]
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_one(name, scope = nil, null_object: nil, **options, &extension)
|
25
|
+
return super(name, scope, **options, &extension) if null_object.nil?
|
26
|
+
|
27
|
+
# generate getter
|
28
|
+
super(name, scope, **options, &extension)
|
29
|
+
|
30
|
+
# decorate getter
|
31
|
+
include Decorator[name, null_object:]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NullAssociation
|
4
|
+
module Decorator
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def [](association_name, null_object: nil)
|
8
|
+
Module.new do
|
9
|
+
define_method association_name do
|
10
|
+
super().presence || case null_object
|
11
|
+
in String => class_name
|
12
|
+
class_name.classify.constantize.new
|
13
|
+
in Class => klass if klass < Singleton
|
14
|
+
klass.instance
|
15
|
+
in Singleton => singleton
|
16
|
+
singleton
|
17
|
+
in Class => klass
|
18
|
+
klass.new
|
19
|
+
in Object => instance
|
20
|
+
instance
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/null_association.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
require_relative 'null_association/concern'
|
7
|
+
require_relative 'null_association/decorator'
|
3
8
|
require_relative 'null_association/version'
|
9
|
+
require_relative 'null_association/railtie'
|
10
|
+
|
11
|
+
module NullAssociation; end
|
4
12
|
|
5
|
-
module NullAssociation
|
6
|
-
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: null_association
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 1.0.0.pre.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeke Gabrielse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,6 +38,62 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: temporary_tables
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sqlite3
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mysql2
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pg
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
41
97
|
description: Decorate nil Active Record associations with a null object in Rails.
|
42
98
|
email:
|
43
99
|
- oss@keygen.sh
|
@@ -51,6 +107,9 @@ files:
|
|
51
107
|
- README.md
|
52
108
|
- SECURITY.md
|
53
109
|
- lib/null_association.rb
|
110
|
+
- lib/null_association/concern.rb
|
111
|
+
- lib/null_association/decorator.rb
|
112
|
+
- lib/null_association/railtie.rb
|
54
113
|
- lib/null_association/version.rb
|
55
114
|
homepage: https://github.com/keygen-sh/null_association
|
56
115
|
licenses:
|
@@ -67,9 +126,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
126
|
version: '3.1'
|
68
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
128
|
requirements:
|
70
|
-
- - "
|
129
|
+
- - ">"
|
71
130
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
131
|
+
version: 1.3.1
|
73
132
|
requirements: []
|
74
133
|
rubygems_version: 3.4.13
|
75
134
|
signing_key:
|