rails_onboarding 0.8.12 → 0.8.14

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: 532f89d681d2a2bf5cdf575a99b26742497707b65c1109525f51307d09bc50c6
4
- data.tar.gz: 6f5e6c0c374b350ac09ac25c36846ad93eee2c2e10d31a531629f65cb19062f7
3
+ metadata.gz: 92019b01af432fe5d1e17c6f116c224d6123f15aeda35798193a3d2a6eb46b3d
4
+ data.tar.gz: ddb5d7f350286ab8512626eae34967b524dfa5284547794b801ca4d1b11fdcbc
5
5
  SHA512:
6
- metadata.gz: 68277199c94e5109304653b498934f8971779b6fe58696133b992b365753527545b06982f013e75faa2fd34e4cb7f71f4730937c2c599da30efdbd0a218d7f7e
7
- data.tar.gz: f2b95e0a399d1981f5f01783231179ea62d7398e8145f0aed809e0621f158c8949e1152c8305f9c5f05daf328350eddf4a293885f954dfa99400c5bf8dac491f
6
+ metadata.gz: da8ba6db11ce280647bee31ad9a718f63cb251d420d2c65d86412363db586d8d16d9c09c95e0ddd128b72bb3cbdd3903f7559391dc271339e6db32451f40405c
7
+ data.tar.gz: ef5428f53020a250d118eb58316ec24dffaa06cc0e364d91fe40bf23c78f97ca56ec7ae15b928e93be7e2e3dfb4d093d2ccd3e8e6957d118df775e7285f27b6f
@@ -26,7 +26,14 @@ module RailsOnboarding
26
26
  included do
27
27
  # Store A/B test assignments as JSON
28
28
  # Expected column: ab_test_assignments (jsonb or text)
29
- serialize :ab_test_assignments, coder: JSON unless column_names.include?("ab_test_assignments") && columns_hash["ab_test_assignments"].type == :jsonb
29
+ # column_names and columns_hash both query the database, and this runs
30
+ # when the host model is loaded -- possibly before the table exists.
31
+ # See RailsOnboarding::SchemaGuard.
32
+ if RailsOnboarding::SchemaGuard.columns_queryable?(self)
33
+ unless column_names.include?("ab_test_assignments") && columns_hash["ab_test_assignments"].type == :jsonb
34
+ serialize :ab_test_assignments, coder: JSON
35
+ end
36
+ end
30
37
 
31
38
  # Callbacks
32
39
  after_initialize :assign_ab_test_variants, if: :new_record?
@@ -7,6 +7,12 @@ module RailsOnboarding
7
7
  MAX_MILESTONES_ACHIEVED = 500
8
8
  MAX_JSON_SIZE_BYTES = 65_535 # ~64KB for TEXT columns
9
9
 
10
+ # Whether the host model's columns can be read yet. See
11
+ # RailsOnboarding::SchemaGuard, which three concerns share.
12
+ def self.columns_queryable?(model)
13
+ SchemaGuard.columns_queryable?(model)
14
+ end
15
+
10
16
  included do
11
17
  # Add fields via migration or expect them in the host model
12
18
  # The host app should have these columns:
@@ -21,17 +27,21 @@ module RailsOnboarding
21
27
  # - onboarding_replay_started_at: datetime
22
28
  # - onboarding_replay_steps: text (serialized JSON array)
23
29
 
24
- # Fix for Rails 8: Use the new serialize syntax
25
- if columns_hash["feature_tooltips_shown"]&.type == :text
26
- serialize :feature_tooltips_shown, coder: JSON
27
- end
30
+ # Fix for Rails 8: Use the new serialize syntax.
31
+ # Guarded because columns_hash queries the database -- see
32
+ # RailsOnboarding::SchemaGuard.
33
+ if RailsOnboarding::SchemaGuard.columns_queryable?(self)
34
+ if columns_hash["feature_tooltips_shown"]&.type == :text
35
+ serialize :feature_tooltips_shown, coder: JSON
36
+ end
28
37
 
29
- if columns_hash["milestones_achieved"]&.type == :text
30
- serialize :milestones_achieved, coder: JSON
31
- end
38
+ if columns_hash["milestones_achieved"]&.type == :text
39
+ serialize :milestones_achieved, coder: JSON
40
+ end
32
41
 
33
- if columns_hash["onboarding_replay_steps"]&.type == :text
34
- serialize :onboarding_replay_steps, coder: JSON
42
+ if columns_hash["onboarding_replay_steps"]&.type == :text
43
+ serialize :onboarding_replay_steps, coder: JSON
44
+ end
35
45
  end
36
46
 
37
47
  # Association with analytics events (only if ActiveRecord is available)
@@ -56,6 +66,7 @@ module RailsOnboarding
56
66
  # than raising on a column that isn't there.
57
67
  def onboarding_replay_supported?
58
68
  return false unless respond_to?(:column_names)
69
+ return false unless RailsOnboarding::SchemaGuard.columns_queryable?(self)
59
70
 
60
71
  column_names.include?("onboarding_replay_started_at") &&
61
72
  column_names.include?("onboarding_replay_steps")
@@ -36,7 +36,14 @@ module RailsOnboarding
36
36
  included do
37
37
  # Store revealed features as JSON
38
38
  # Expected column: revealed_features (jsonb or text)
39
- serialize :revealed_features, coder: JSON unless column_names.include?("revealed_features") && columns_hash["revealed_features"].type == :jsonb
39
+ # column_names and columns_hash both query the database, and this runs
40
+ # when the host model is loaded -- possibly before the table exists.
41
+ # See RailsOnboarding::SchemaGuard.
42
+ if RailsOnboarding::SchemaGuard.columns_queryable?(self)
43
+ unless column_names.include?("revealed_features") && columns_hash["revealed_features"].type == :jsonb
44
+ serialize :revealed_features, coder: JSON
45
+ end
46
+ end
40
47
 
41
48
  # Callback to check and reveal features
42
49
  after_save :check_progressive_features, if: :saved_change_to_onboarding_current_step?
@@ -0,0 +1,38 @@
1
+ module RailsOnboarding
2
+ # Whether a host model's columns can be read yet.
3
+ #
4
+ # Three concerns inspect columns the moment they are included -- to decide
5
+ # whether to configure JSON serialization -- and `columns_hash` and
6
+ # `column_names` both query the database. That runs when the host model is
7
+ # loaded, which can be long before the table exists.
8
+ #
9
+ # A host that references its user model from an initializer hits this
10
+ # immediately. The common OmniAuth `:identity` setup passes `model: User`, so
11
+ # the model loads during boot and the process dies with
12
+ # `Table 'users' doesn't exist`. That is circular and unrecoverable: loading
13
+ # the schema requires booting the app, and booting the app requires the
14
+ # schema. It stops `db:prepare` bootstrapping a genuinely new database, a
15
+ # restore into an empty schema, and CI against a fresh database service.
16
+ module SchemaGuard
17
+ module_function
18
+
19
+ # Only ever answers false when the table is positively known to be absent.
20
+ #
21
+ # These concerns are deliberately includable into plain classes that are not
22
+ # ActiveRecord models -- hence the `respond_to?(:has_many)` and
23
+ # `respond_to?(:validate)` guards in Onboardable -- and such a class answers
24
+ # `columns_hash` while having no `table_exists?`. Vetoing those would
25
+ # silently stop configuring them, so anything that cannot be asked is
26
+ # treated as queryable and left to the callers' own guards, exactly as
27
+ # before this check existed.
28
+ def columns_queryable?(model)
29
+ return true unless model.respond_to?(:table_exists?)
30
+
31
+ model.table_exists?
32
+ rescue ActiveRecord::NoDatabaseError,
33
+ ActiveRecord::ConnectionNotEstablished,
34
+ ActiveRecord::StatementInvalid
35
+ false
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsOnboarding
2
- VERSION = "0.8.12"
2
+ VERSION = "0.8.14"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_onboarding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.12
4
+ version: 0.8.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Lewis
@@ -183,6 +183,7 @@ files:
183
183
  - app/models/concerns/rails_onboarding/onboardable.rb
184
184
  - app/models/concerns/rails_onboarding/personalizable.rb
185
185
  - app/models/concerns/rails_onboarding/progressive_disclosure.rb
186
+ - app/models/concerns/rails_onboarding/schema_guard.rb
186
187
  - app/models/rails_onboarding/analytics.rb
187
188
  - app/models/rails_onboarding/analytics_event.rb
188
189
  - app/models/rails_onboarding/application_record.rb
@@ -282,7 +283,7 @@ licenses:
282
283
  metadata:
283
284
  allowed_push_host: https://rubygems.org
284
285
  homepage_uri: https://github.com/bunnahabhain/rails_onboarding
285
- source_code_uri: https://github.com/bunnahabhain/rails_onboarding/tree/v0.8.12
286
+ source_code_uri: https://github.com/bunnahabhain/rails_onboarding/tree/v0.8.14
286
287
  changelog_uri: https://github.com/bunnahabhain/rails_onboarding/blob/master/docs/CHANGELOG.md
287
288
  rdoc_options: []
288
289
  require_paths: