Module: Permittable::ColumnGuard
- Defined in:
- lib/permittable/column_guard.rb
Overview
Schema validation behind the drift guard. When the schema is unreachable —
no database yet (db:create, a fresh db:migrate, assets:precompile,
CI bootstrap) or the table not yet migrated — the check is skipped and
false is returned instead of raising, so controller classes stay
loadable. A missing column with a reachable schema still raises: the
rescue is scoped to ActiveRecord::ActiveRecordError precisely so real bugs
(NameError from a typo etc.) keep surfacing. Skipping is self-healing:
once the migration runs and classes reload, validation happens for real.
Class Method Summary collapse
- .column_migration_hint(klass, field, types) ⇒ Object
-
.ensure_columns_on!(label, klass, *fields, types: nil) ⇒ Object
types:teaches the error message: a Symbol/String applies to every listed field, a Hash maps field => type. -
.schema_reachable?(klass) ⇒ Boolean
True when the class's table can actually be inspected.
Class Method Details
.column_migration_hint(klass, field, types) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/permittable/column_guard.rb', line 31 def column_migration_hint(klass, field, types) type = types.is_a?(Hash) ? types[field.to_sym] : types column = [field, type].compact.join(":") " Add it with: bin/rails generate migration " \ "Add#{field.to_s.camelize}To#{klass.table_name.to_s.camelize} #{column}" end |
.ensure_columns_on!(label, klass, *fields, types: nil) ⇒ Object
types: teaches the error message: a Symbol/String applies to every
listed field, a Hash maps field => type. The raised ArgumentError then
appends a ready-to-paste migration command.
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/permittable/column_guard.rb', line 18 def ensure_columns_on!(label, klass, *fields, types: nil) return false unless schema_reachable?(klass) fields.flatten.compact.each do |field| next if klass.column_names.include?(field.to_s) raise ArgumentError, "#{label}: '#{field}' does not exist in the database (table: #{klass.table_name})." \ "#{column_migration_hint(klass, field, types)}" end true end |
.schema_reachable?(klass) ⇒ Boolean
True when the class's table can actually be inspected. Connection errors
(ConnectionNotEstablished, NoDatabaseError, adapter errors) all inherit
from ActiveRecord::ActiveRecordError; the defined? guard keeps this gem
loadable without activerecord (a host without it cannot pass model:
anyway).
43 44 45 46 47 48 49 |
# File 'lib/permittable/column_guard.rb', line 43 def schema_reachable?(klass) klass.table_exists? rescue StandardError => e raise unless defined?(ActiveRecord::ActiveRecordError) && e.is_a?(ActiveRecord::ActiveRecordError) false end |