Module: Pilipinas::Db::Concerns::StaticRecord
- Extended by:
- ActiveSupport::Concern
- Included in:
- Barangay, Pilipinas::Db::City, Province, Region
- Defined in:
- lib/pilipinas/db/concerns/static_record.rb
Overview
Shared ActiveRecord concern applied to every Pilipinas DB model.
What this solves
The four pilipinas_* tables hold static reference data that never changes after the initial seed. Plain ActiveRecord has several sources of unnecessary memory allocation for this workload:
- All columns are loaded by default, including lft/rgt (nested-set hierarchy fields), longitude/latitude, income_class, etc. — most callers only ever need code + name.
- STI type-column checking — AR looks for a
typecolumn on every query; these tables have none, so that check is pure overhead. - Dirty-tracking and callbacks — pointless for read-only data.
- Accidental writes — a stray
saveorupdateon static data is almost always a bug; it should raise immediately. - Unbatched mass loads — loading 42 k+ barangay rows in a single SQL statement creates a huge transient Array before AR can even instantiate objects.
Optimizations applied
readonly?returnstruefor persisted records whenenforce_readonlyistrue(the default) — accidentalupdate!/save!/destroyon fetched rows raiseActiveRecord::ReadOnlyRecord; new records stay writable so the Loader and test fixtures can still callcreate!.enforce_readonlyclass attribute: opt a subclass out of the read-only guard without touching production models — useful in test environments where factories need to write to pilipinas tables.self.inheritance_column = :_sti_disabled: removes STI type-column look-up from every query..litescope: selects onlyid,location_id,code,name— skips every spatial/hierarchy column, ~60 % less data per row for the barangays table (the largest one)..by_code/.by_namescopes: paired with.litethese give the caller a single, readable one-liner that minimises allocations.- Association lambdas on has_many restrict the SELECT to the five
columns actually needed for traversal, so
region.provinces,province.cities, andcity.barangaysare all automatically lean.
Constant Summary collapse
- LITE_COLUMNS =
Columns loaded for associations and the
litescope. Excludes: lft, rgt, longitude, latitude, parent_id (for lite), income_class, urban_rural, district, timestamps. %i[id location_id code name].freeze
- TRAVERSAL_COLUMNS =
%i[id location_id parent_id code name].freeze
Instance Method Summary collapse
-
#readonly? ⇒ Boolean
Guards against accidental writes to static reference data.
Instance Method Details
#readonly? ⇒ Boolean
Guards against accidental writes to static reference data.
Returns true (making the record read-only) when both conditions hold:
- The record is persisted (+new_record?+ is
false). - The class-level
enforce_readonlyflag istrue(the default).
New (unsaved) objects are always writable so the Loader and test
factories can call create!. To allow writes on a subclass — for
example in a test environment — set:
self.enforce_readonly = false
Overriding readonly? is more efficient than an after_initialize
callback: it is only invoked when AR is about to perform a write
operation, so it adds zero overhead on read paths.
136 137 138 |
# File 'lib/pilipinas/db/concerns/static_record.rb', line 136 def readonly? self.class.enforce_readonly && !new_record? end |