passive_columns 0.3.4 → 0.3.5
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 +24 -0
- data/lib/passive_columns/loader.rb +14 -1
- data/lib/passive_columns/version.rb +1 -1
- data/lib/passive_columns.rb +29 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db1546c471db3b31751f758a4787d689707e1202f7662485f2710ccdb1e72bd1
|
|
4
|
+
data.tar.gz: '0486b7f619953eb457c5d3743c44c6171718ed5573a22cb3b2674c5f7928987b'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63e2a1db74d7430af2c98b7d837866d74eefeb90d68075ebf74ef8e4e35da35dec147c60b9a026be89d6e33d4180deca6584fbb7e1e51e478d456225f66515e4
|
|
7
|
+
data.tar.gz: 7062e8a4565dece1d5d341c8b50761356c5c11efb546de15ed4b513d98a0d83c6e04cb0f9db24f2cbc7b7c4ce7e666baf8e8f9c19d500050cf786e7e3fe2d424
|
data/README.md
CHANGED
|
@@ -37,6 +37,27 @@ But you still has an ability to retrieve the passive column on demand
|
|
|
37
37
|
page.huge_article # => 'Some huge article...'
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### Eager-loading passive columns in the same query
|
|
41
|
+
|
|
42
|
+
Use `with_passive_columns` when you want passive columns included in the main `SELECT` instead of loading them later.
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
# All columns (including every passive column)
|
|
46
|
+
Page.with_passive_columns
|
|
47
|
+
|
|
48
|
+
# Default non-passive columns plus only the passive columns you list.
|
|
49
|
+
# Any names that are not passive columns are ignored.
|
|
50
|
+
Page.with_passive_columns(:huge_article)
|
|
51
|
+
|
|
52
|
+
# On an association (scope is on the associated model):
|
|
53
|
+
user.pages.with_passive_columns(:huge_article)
|
|
54
|
+
|
|
55
|
+
# Equivalent when you already have a relation object to merge:
|
|
56
|
+
user.pages.merge(Page.with_passive_columns(:huge_article))
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`find` / `find_by` still use the default selection unless you chain `with_passive_columns` explicitly (for example `Page.with_passive_columns.find(id)`).
|
|
60
|
+
|
|
40
61
|
---
|
|
41
62
|
|
|
42
63
|
|
|
@@ -65,6 +86,9 @@ user.name
|
|
|
65
86
|
|
|
66
87
|
By the way, it uses the Rails' `.pick` method to get the value of the column under the hood
|
|
67
88
|
|
|
89
|
+
### Logging on-demand SQL loads
|
|
90
|
+
|
|
91
|
+
Whenever a passive attribute reader or `load_column` runs the extra `pick` query, the gem logs one **`debug`** line (prefix `[passive_columns]`, model, column, and primary-key context) **only if** `model.logger` is set — there is no fallback to `ActiveRecord::Base.logger`. Like other debug lines, it appears only when that logger’s level is **debug** (typical in `development`, usually not at `info` in production).
|
|
68
92
|
|
|
69
93
|
### Important
|
|
70
94
|
|
|
@@ -20,16 +20,29 @@ module PassiveColumns
|
|
|
20
20
|
|
|
21
21
|
model.send(column)
|
|
22
22
|
rescue ActiveModel::MissingAttributeError
|
|
23
|
+
materialize_missing_column(column, force)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def materialize_missing_column(column, force)
|
|
23
29
|
allowed_columns = (force ? [column] : passive_columns).map(&:to_s)
|
|
24
30
|
raise if allowed_columns.exclude?(column.to_s) || identity_constraints.value?(nil)
|
|
25
31
|
|
|
32
|
+
log_lazy_sql_load(column)
|
|
26
33
|
value = pick_value(column)
|
|
27
34
|
model[column] = value
|
|
28
35
|
model.send(:clear_attribute_change, column)
|
|
29
36
|
model[column]
|
|
30
37
|
end
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
def log_lazy_sql_load(column)
|
|
40
|
+
logger = model.logger
|
|
41
|
+
return unless logger&.debug?
|
|
42
|
+
|
|
43
|
+
ctx = identity_constraints.map { |k, v| "#{k}=#{v.inspect}" }.join(', ')
|
|
44
|
+
logger.debug("[passive_columns] On-demand SQL load of #{model.class.name}##{column} (#{ctx})")
|
|
45
|
+
end
|
|
33
46
|
|
|
34
47
|
def pick_value(column)
|
|
35
48
|
model.class.unscoped.where(identity_constraints).pick(column)
|
data/lib/passive_columns.rb
CHANGED
|
@@ -33,11 +33,40 @@ require 'passive_columns/loader'
|
|
|
33
33
|
#
|
|
34
34
|
# The next time you call the passive column it won't hit the database as it is already loaded.
|
|
35
35
|
# page.huge_article # => 'Some huge article...'
|
|
36
|
+
#
|
|
37
|
+
# To load passive columns in the same query, use +with_passive_columns+ with no arguments (all passive columns)
|
|
38
|
+
# or pass passive column names; any other names are ignored.
|
|
39
|
+
# Page.with_passive_columns.to_a
|
|
40
|
+
# Page.with_passive_columns(:huge_article).to_a
|
|
36
41
|
module PassiveColumns
|
|
37
42
|
extend ActiveSupport::Concern
|
|
38
43
|
|
|
39
44
|
included do
|
|
40
45
|
class_attribute :_passive_columns, default: []
|
|
46
|
+
|
|
47
|
+
# Eager-load passive columns in the main SELECT instead of omitting them.
|
|
48
|
+
# With no arguments, sets +select_values+ to all +column_names+ (including passive columns);
|
|
49
|
+
# Active Record turns that into the SELECT list.
|
|
50
|
+
# With arguments, only names listed in +passive_columns+ are merged into +select_values+ with
|
|
51
|
+
# the usual non-passive column list; other names are ignored. If none of the arguments are
|
|
52
|
+
# passive columns, the relation behaves like a normal query (passive columns still omitted).
|
|
53
|
+
#
|
|
54
|
+
# @param [Array<Symbol, String>] requested
|
|
55
|
+
# @return [ActiveRecord::Relation]
|
|
56
|
+
scope(:with_passive_columns, lambda do |*requested|
|
|
57
|
+
return self if klass._passive_columns.blank?
|
|
58
|
+
|
|
59
|
+
if requested.empty?
|
|
60
|
+
spawn.tap { |r| r.select_values = klass.column_names.dup }
|
|
61
|
+
else
|
|
62
|
+
passive_only = requested.map(&:to_s).uniq.select { |c| klass._passive_columns.include?(c) }
|
|
63
|
+
return self if passive_only.empty?
|
|
64
|
+
|
|
65
|
+
spawn.tap do |r|
|
|
66
|
+
r.select_values = klass.column_names - klass._passive_columns + passive_only
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end)
|
|
41
70
|
end
|
|
42
71
|
|
|
43
72
|
class_methods do # rubocop:disable Metrics/BlockLength
|
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.3.
|
|
4
|
+
version: 0.3.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitrii Golovin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|