passive_columns 0.2.1 → 0.3.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 +4 -4
- data/README.md +47 -4
- data/lib/passive_columns/active_record_relation_extension.rb +13 -4
- data/lib/passive_columns/loader.rb +12 -4
- data/lib/passive_columns/version.rb +1 -1
- data/lib/passive_columns.rb +7 -3
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: baf809905aa69dc2f9ee36bcb51c2c2187790c2d2455fdb0ba828546c260625f
|
|
4
|
+
data.tar.gz: 005e105b072004ef89f410d4470a760be689b589a9f767c6a907e31e7ffd9644
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 02f54e4528a456f37d07e6340bbc0aeb01c672db28002ad681d5394c8d4617f3bf50ae97b1eaaa13c1d4561712554e95d5612ec239fe0bf2f246db2316f2cf6c
|
|
7
|
+
data.tar.gz: 72b5738f265fdc05deb98defee7853fc37427ed8922e19f0e1911bffd9cbe20e48a5a62b49afc188096e6cb9a01c958b1b851f7a1fca709d2332ea10ad4c585f
|
data/README.md
CHANGED
|
@@ -66,6 +66,43 @@ user.name
|
|
|
66
66
|
By the way, it uses the Rails' `.pick` method to get the value of the column under the hood
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
### Important
|
|
70
|
+
|
|
71
|
+
If you want `passive_columns` to skip validation rules specific to the columns you exclude.<br>
|
|
72
|
+
(in case they were not retrieved / modified)
|
|
73
|
+
```ruby
|
|
74
|
+
validates :huge_article, presence: true
|
|
75
|
+
# Will be transformed into:
|
|
76
|
+
# validates :huge_article, presence: true, if: -> { attributes.key?('huge_article') }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
You must declare validation rules for `passive_columns` separately
|
|
80
|
+
```ruby
|
|
81
|
+
class Page < ActiveRecord::Base
|
|
82
|
+
include PassiveColumns
|
|
83
|
+
passive_columns :huge_article # Declare columns above the validation rules.
|
|
84
|
+
|
|
85
|
+
validates :name, presence: true
|
|
86
|
+
# Validation rules transformation will work
|
|
87
|
+
validates :huge_article, presence: true # It works for a separate rule.
|
|
88
|
+
# -> the rule is transformed into:
|
|
89
|
+
# -> validates :huge_article, presence: true, if: -> { attributes.key?('huge_article') }
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
class Page < ActiveRecord::Base
|
|
95
|
+
include PassiveColumns
|
|
96
|
+
passive_columns :huge_article # Declare columns above the validation rules.
|
|
97
|
+
|
|
98
|
+
# Validation rules transformation WON'T work
|
|
99
|
+
validates :name, :huge_article, presence: true # It doesn't work for combined rules.
|
|
100
|
+
# -> the rule remains the same:
|
|
101
|
+
# -> validates :name, :huge_article, presence: true
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
|
|
69
106
|
## Installation
|
|
70
107
|
Add this line to your Gemfile:
|
|
71
108
|
|
|
@@ -123,13 +160,19 @@ One way to avoid this is to check for the presence of the attribute before valid
|
|
|
123
160
|
validates :huge_article, presence: true, if: -> { attributes.key?('huge_article') }
|
|
124
161
|
```
|
|
125
162
|
|
|
126
|
-
Unfortunately, boilerplate code is needed for such a simple task.
|
|
127
|
-
|
|
163
|
+
Unfortunately, boilerplate code is needed for such a simple task. <br>
|
|
164
|
+
But the only thing you wanted was to exclude some columns and be able to manipulate a model without extra steps.
|
|
165
|
+
|
|
166
|
+
By the way, after doing those steps, you still cannot retrieve the column when you need it after loading the scoped model...
|
|
128
167
|
|
|
129
|
-
`passive_columns` tries to solve this problem by allowing you to exclude columns from the selection
|
|
130
|
-
and also allows you to retrieve them on demand when needed.
|
|
168
|
+
So, `passive_columns` tries to solve this problem by allowing you to exclude columns from the selection and also allowing you to retrieve them on demand when needed.
|
|
131
169
|
|
|
170
|
+
---
|
|
132
171
|
|
|
172
|
+
#### Inspiration
|
|
173
|
+
There are similar gems that were relatively popular but are no longer supported. Let's give them the honor they deserve:
|
|
174
|
+
- [lazy_columns](https://github.com/jorgemanrubia/lazy_columns)
|
|
175
|
+
- [columns_on_demand](https://github.com/willbryant/columns_on_demand)
|
|
133
176
|
|
|
134
177
|
## License
|
|
135
178
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -4,11 +4,20 @@ module PassiveColumns
|
|
|
4
4
|
# ActiveRecordRelationExtension is a module that extends ActiveRecord::Relation
|
|
5
5
|
# to automatically select all columns except passive columns if no columns are selected.
|
|
6
6
|
module ActiveRecordRelationExtension
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
|
8
|
+
def exec_main_query(...)
|
|
9
|
+
if klass.try(:_passive_columns).present? && select_values.blank?
|
|
10
|
+
self.select_values = klass.column_names - klass._passive_columns
|
|
11
|
+
end
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
def exec_queries(...)
|
|
16
|
+
if klass.try(:_passive_columns).present? && select_values.blank?
|
|
17
|
+
self.select_values = klass.column_names - klass._passive_columns
|
|
18
|
+
end
|
|
19
|
+
super
|
|
10
20
|
end
|
|
11
|
-
super
|
|
12
21
|
end
|
|
13
22
|
|
|
14
23
|
def to_sql
|
|
@@ -5,7 +5,7 @@ module PassiveColumns
|
|
|
5
5
|
class Loader
|
|
6
6
|
attr_reader :passive_columns, :model
|
|
7
7
|
|
|
8
|
-
# @param [
|
|
8
|
+
# @param [ActiveRecord::Base] model
|
|
9
9
|
# @param [Array<Symbol>] passive_columns
|
|
10
10
|
def initialize(model, passive_columns)
|
|
11
11
|
@model = model
|
|
@@ -26,7 +26,7 @@ module PassiveColumns
|
|
|
26
26
|
value = pick_value(column)
|
|
27
27
|
model[column] = value
|
|
28
28
|
model.send(:clear_attribute_change, column)
|
|
29
|
-
|
|
29
|
+
model[column]
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
private
|
|
@@ -35,8 +35,16 @@ module PassiveColumns
|
|
|
35
35
|
model.class.unscoped.where(identity_constraints).pick(column)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
|
39
|
+
def identity_constraints
|
|
40
|
+
@identity_constraints ||= model.send(:_query_constraints_hash)
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
def identity_constraints
|
|
44
|
+
@identity_constraints ||= {
|
|
45
|
+
model.instance_variable_get(:@primary_key) => model.id_in_database
|
|
46
|
+
}
|
|
47
|
+
end
|
|
40
48
|
end
|
|
41
49
|
end
|
|
42
50
|
end
|
data/lib/passive_columns.rb
CHANGED
|
@@ -83,9 +83,13 @@ module PassiveColumns
|
|
|
83
83
|
# Otherwise, the passive column will be retrieved from DB before validation itself.
|
|
84
84
|
def set_callback(name, *filter_list, &block)
|
|
85
85
|
opts = filter_list.extract_options!
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
opts[:
|
|
86
|
+
|
|
87
|
+
if name == :validate
|
|
88
|
+
attrs = opts[:attributes] || filter_list[0].try(:attributes)
|
|
89
|
+
if attrs&.one?
|
|
90
|
+
passive_column = attrs.map(&:to_s) & _passive_columns
|
|
91
|
+
opts[:if] = ([-> { attributes.key?(passive_column.first) }] + Array(opts[:if])) if passive_column.present?
|
|
92
|
+
end
|
|
89
93
|
end
|
|
90
94
|
super(name, *filter_list, opts, &block)
|
|
91
95
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: passive_columns
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Golovin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-07-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -16,28 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '6.1'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '6.1'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: activesupport
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '6.1'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '6.1'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|