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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1dda0f9908da208e37e6a916682dca1694dd57ff1093235e75071a38e35ebd0
4
- data.tar.gz: 6d320b51823509635303c91f90c116170db1c2a2f44559443948629a630872ba
3
+ metadata.gz: db1546c471db3b31751f758a4787d689707e1202f7662485f2710ccdb1e72bd1
4
+ data.tar.gz: '0486b7f619953eb457c5d3743c44c6171718ed5573a22cb3b2674c5f7928987b'
5
5
  SHA512:
6
- metadata.gz: 4002b0fff7d1563677d309215c1b6de3755206df2ea99cc71cdeb2df5089d39e8883fb4954bbacb3bb23427eb46fa86fa2d13ca7b707ddcf39bc9bb038b1c1f5
7
- data.tar.gz: 655257c23cd3ee05d2941236b4af332f293270a2bb5023606df1053b1b41c6ef44c75a87ccc756f35cd89fdd85271819512fe760bc63f16e388f0a9357edad78
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
- private
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PassiveColumns
4
- VERSION = '0.3.4'
4
+ VERSION = '0.3.5'
5
5
  end
@@ -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
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-01-02 00:00:00.000000000 Z
11
+ date: 2026-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord