A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
class
PlaceOS::Model::Group
- PlaceOS::Model::Group
- PgORM::Base
- ActiveModel::Model
- Reference
- Object
Overview
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Included Modules
- PgORM::Timestamps
- PlaceOS::Model::History::Tracked
Defined in:
placeos-models/group.crConstant Summary
-
CALLBACKS =
{before_save: [do if (__temp_1337 = @authority) && __temp_1337.new_record? __temp_1337.save self.authority_id = __temp_1337.id.not_nil! end end, do if (__temp_1338 = @parent) && __temp_1338.new_record? __temp_1338.save self.parent_id = __temp_1338.id.not_nil! end end, :normalize_ad_group_mappings] of Nil, after_save: [] of Nil, before_create: [do self.created_at = self.updated_at = Time.utc end] of Nil, after_create: [] of Nil, before_update: [do self.updated_at = Time.utc end] of Nil, after_update: [] of Nil, before_destroy: [] of Nil, after_destroy: [do end, do end, :__record_history_destroy__] of Nil} -
A node in the group tree for an authority. The tree represents the organisational hierarchy. Each group declares which subsystems (signage, events, parking, ...) it participates in via the
#subsystemstext array; subsystem-scoped permission queries are filtered against that array. An authority may have several root groups (#parent_idnil), each heading its own independent tree. -
MAX_FEATURE_DEPTH =
2 -
Objects may nest inside a feature value at most this many levels deep.
-
MAX_FEATURE_KEY_SIZE =
64 -
PRIMARY_KEY_TYPES =
{:id => UUID} of Nil => Nil -
macro level key => type
-
PRIMARY_KEYS =
[{:id}] -
A node in the group tree for an authority. The tree represents the organisational hierarchy. Each group declares which subsystems (signage, events, parking, ...) it participates in via the
#subsystemstext array; subsystem-scoped permission queries are filtered against that array. An authority may have several root groups (#parent_idnil), each heading its own independent tree.
Constructors
-
.from_json(string_or_io : String | IO, trusted : Bool = false) : self
A node in the group tree for an authority.
-
.from_json(string_or_io : String | IO, root : String, trusted : Bool = false) : self
Deserializes the given JSON in string_or_io into an instance of
self, assuming the JSON consists of an JSON object with key root, and whose value is the value to deserialize. -
.from_trusted_json(string_or_io : String | IO, root : String) : self
A node in the group tree for an authority.
-
.from_trusted_json(string_or_io : String | IO) : self
Serialize from a trusted JSON source
-
.from_trusted_yaml(string_or_io : String | IO) : self
Serialize from a trusted YAML source
-
.from_yaml(string_or_io : String | IO, trusted : Bool = false) : self
A node in the group tree for an authority.
-
.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
A node in the group tree for an authority.
-
.new(pull : JSON::PullParser)
A node in the group tree for an authority.
-
.new(rs : DB::ResultSet)
A node in the group tree for an authority.
-
.new(created_at : Time | ActiveModel::Model::None = ::ActiveModel::Model::None.new, updated_at : Time | ActiveModel::Model::None = ::ActiveModel::Model::None.new, id : UUID | ActiveModel::Model::None = ::ActiveModel::Model::None.new, name : String | ActiveModel::Model::None = ::ActiveModel::Model::None.new, description : String | ActiveModel::Model::None = ::ActiveModel::Model::None.new, subsystems : Array(String) | ActiveModel::Model::None = ::ActiveModel::Model::None.new, default_permissions : Int32 | ActiveModel::Model::None = ::ActiveModel::Model::None.new, ad_group_mappings : Hash(String, Tuple(String, Int32)) | ActiveModel::Model::None = ::ActiveModel::Model::None.new, features : Hash(String, Hash(String, JSON::Any)) | ActiveModel::Model::None = ::ActiveModel::Model::None.new, authority_id : String | ActiveModel::Model::None = ::ActiveModel::Model::None.new, parent_id : UUID | Nil | ActiveModel::Model::None = ::ActiveModel::Model::None.new)
A node in the group tree for an authority.
-
.new(params : HTTP::Params | Hash(String, String) | Tuple(String, String))
Initialize PlaceOS::Model::Group from
HTTP::Params. -
.undelete(resource_id : String) : self
Recreates a deleted record from its latest
deleteentry, keeping its id.
Class Method Summary
-
.accessible_zone_ids(authority_id : String, subsystem : String, user_id : String) : Array(String)
Zone ids this user has any non-zero effective permission on, within
subsystem. -
.accessible_zones_sql(authority_id : String, subsystems : Array(String), user_id : String, required : Permissions) : String | Nil
Returns a self-contained SQL subquery (single column: zone id) yielding every zone where the user's effective permissions within any of
#subsystemssatisfyrequired(Manage is a superset). -
.add_remove_ad_groups(authority_id : String, user_id : String, ad_groups : Array(String)) : Nil
Syncs a user's automatic group memberships with the AD groups they are currently a member of, within
#authority_id: -
.attributes : Array(Symbol)
Returns all attribute keys.
- .by_authority_id(id)
- .by_parent_id(id)
-
.change_history(resource_id : String)
Entries recorded for the resource, newest first
-
.changefeed_ignored_update_columns : Array(String) | Nil
A node in the group tree for an authority.
-
.changes(id : UUID | Nil = nil) : ChangeFeed
Changefeed at row (if
#idpassed) or whole table level. -
.effective_permissions(authority_id : String, subsystem : String, user_id : String, zone_id : String) : Permissions
Effective permission bitmask for (user, zone) within
subsystem. -
.effective_permissions(authority_id : String, subsystem : String, user_id : String, zone_ids : Array(String)) : Permissions
Effective permissions across a batch of zones.
-
.from_rs(__temp_2555 : DB::ResultSet)
A node in the group tree for an authority.
-
.history_ignored : Array(String)
Fields not recorded, changes to only these fields are not recorded at all
-
.history_redacted : Array(String)
Fields whose values are never recorded
-
.on_error(err : Exception | IO::Error)
A node in the group tree for an authority.
-
.primary_key
A node in the group tree for an authority.
-
.resolve_subsystem_permissions(authority_id : String, subsystem : String, user_id : String) : Hash(String, Permissions)
Full
{zone_id => Permissions}map for the user withinsubsystem. -
.table_name
A node in the group tree for an authority.
-
.zone_accessible?(authority_id : String, subsystem : String, user_id : String, zone_id : String) : Bool
Does this user have any non-zero effective permission on this zone (directly or transitively) for
subsystem?
Instance Method Summary
-
#ad_group_mappings : Hash(String, Tuple(String, Int32))
#ad_group_mappingsgetter -
#ad_group_mappings=(value : Hash(String, Tuple(String, Int32)))
#ad_group_mappingssetter -
#ad_group_mappings? : Hash(String, Tuple(String, Int32)) | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#ad_group_mappings_assigned? : Bool
A node in the group tree for an authority.
-
#ad_group_mappings_change : Tuple(Hash(String, Tuple(String, Int32)) | Nil, Hash(String, Tuple(String, Int32)) | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#ad_group_mappings_changed? : Bool
A node in the group tree for an authority.
-
#ad_group_mappings_default : Hash(String, Tuple(String, Int32))
#ad_group_mappings's default value -
#ad_group_mappings_present? : Bool
AD group id => {display name, permissions bitmask}.
-
#ad_group_mappings_removed? : Bool
A node in the group tree for an authority.
-
#ad_group_mappings_was : Hash(String, Tuple(String, Int32)) | Nil
A node in the group tree for an authority.
-
#ad_group_mappings_will_change! : Nil
Include
#ad_group_mappingsin the set of changed attributes, whether it has changed or not. -
#after_create
A node in the group tree for an authority.
-
#after_destroy
A node in the group tree for an authority.
-
#after_initialize(trusted : Bool)
A node in the group tree for an authority.
-
#after_save
A node in the group tree for an authority.
-
#after_update
A node in the group tree for an authority.
-
#apply_defaults
Generate code to apply default values
-
#assign_attributes(created_at : Time | Missing = Missing, updated_at : Time | Missing = Missing, id : UUID | Missing = Missing, name : String | Missing = Missing, description : String | Missing = Missing, subsystems : Array(String) | Missing = Missing, default_permissions : Int32 | Missing = Missing, ad_group_mappings : Hash(String, Tuple(String, Int32)) | Missing = Missing, features : Hash(String, Hash(String, JSON::Any)) | Missing = Missing, authority_id : String | Missing = Missing, parent_id : UUID | Nil | Missing = Missing)
Assign to multiple attributes.
-
#assign_attributes(params : HTTP::Params | Hash(String, String) | Tuple(String, String))
Assign to multiple attributes via
HTTP::Params. -
#assign_attributes(model : PlaceOS::Model::Group)
Assign to multiple attributes from a model object
-
#assign_attributes_from_json(json, root : String)
A node in the group tree for an authority.
-
#assign_attributes_from_json(json)
A node in the group tree for an authority.
-
#assign_attributes_from_trusted_json(json, root : String)
A node in the group tree for an authority.
-
#assign_attributes_from_trusted_json(json)
Assign each field from JSON if field exists in JSON and has changed in model
-
#assign_attributes_from_trusted_yaml(yaml)
A node in the group tree for an authority.
-
#assign_attributes_from_yaml(yaml)
Uses the YAML parser as JSON is valid YAML
-
#attributes
Returns a
Hashof all attribute values -
#attributes_json(io : IO) : Nil
Serialize attributes to JSON, without any other properties
to_jsonmay include, as.from_jsonexpects them. -
#attributes_json(json : JSON::Builder) : Nil
Serialize attributes to JSON, without any other properties
to_jsonmay include, as.from_jsonexpects them. -
#attributes_json : String
Serialize attributes to JSON, without any other properties
to_jsonmay include, as.from_jsonexpects them. -
#attributes_tuple
Returns a
NamedTupleof all attribute values. - #authority : PlaceOS::Model::Authority
- #authority! : PlaceOS::Model::Authority
- #authority=(record : PlaceOS::Model::Authority) : PlaceOS::Model::Authority
- #authority? : PlaceOS::Model::Authority | Nil
-
#authority_id : String
#authority_idgetter -
#authority_id=(value : String)
#authority_idsetter -
#authority_id? : String | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#authority_id_assigned? : Bool
A node in the group tree for an authority.
-
#authority_id_change : Tuple(String | Nil, String | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#authority_id_changed? : Bool
A node in the group tree for an authority.
-
#authority_id_default : String
#authority_id's default value - #authority_id_present? : Bool
-
#authority_id_removed? : Bool
A node in the group tree for an authority.
-
#authority_id_was : String | Nil
A node in the group tree for an authority.
-
#authority_id_will_change! : Nil
Include
#authority_idin the set of changed attributes, whether it has changed or not. -
#before_create
A node in the group tree for an authority.
-
#before_destroy
A node in the group tree for an authority.
-
#before_save
A node in the group tree for an authority.
-
#before_update
A node in the group tree for an authority.
- #build_authority(**attributes) : PlaceOS::Model::Authority
- #build_parent(**attributes) : Group
-
#changed?
Check if any attributes have changed.
-
#changed_attributes
Returns a
Hashwith all changed attributes. -
#changed_json(io : IO) : Nil
Serialize the set of changed attributes to JSON.
-
#changed_json : String
Serialize the set of changed attributes to JSON.
-
#changed_persist_attributes
A node in the group tree for an authority.
-
#changed_yaml(io : IO) : Nil
Serialize the set of changed attributes to YAML.
-
#changed_yaml : String
Serialize the set of changed attributes to YAML.
-
#changes
Returns a
Hashof changed attributes, mapping each to a{previous, current}tuple. -
#changes_json(io : IO) : Nil
Serialize changed attributes to JSON as
{"attribute": [previous, current]}. -
#changes_json(json : JSON::Builder) : Nil
Serialize changed attributes to JSON as
{"attribute": [previous, current]}. -
#changes_json : String
Serialize changed attributes to JSON as
{"attribute": [previous, current]}. -
#children
Immediate children.
-
#clear_changes_information
Reset changes for all attributes.
- #create_authority(**attributes) : PlaceOS::Model::Authority
- #create_authority!(**attributes) : PlaceOS::Model::Authority
- #create_parent(**attributes) : Group
- #create_parent!(**attributes) : Group
-
#created_at : Time
#created_atgetter -
#created_at=(value : Time)
Setters
#created_atsetter -
#created_at? : Time | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#created_at_assigned? : Bool
A node in the group tree for an authority.
-
#created_at_change : Tuple(Time | Nil, Time | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#created_at_changed? : Bool
A node in the group tree for an authority.
-
#created_at_default : Time
#created_at's default value - #created_at_present? : Bool
-
#created_at_removed? : Bool
A node in the group tree for an authority.
-
#created_at_was : Time | Nil
A node in the group tree for an authority.
-
#created_at_will_change! : Nil
Include
#created_atin the set of changed attributes, whether it has changed or not. -
#default_permissions : Int32
#default_permissionsgetter -
#default_permissions=(value : Int32)
#default_permissionssetter -
#default_permissions? : Int32 | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#default_permissions_assigned? : Bool
A node in the group tree for an authority.
-
#default_permissions_change : Tuple(Int32 | Nil, Int32 | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#default_permissions_changed? : Bool
A node in the group tree for an authority.
-
#default_permissions_default : Int32
#default_permissions's default value -
#default_permissions_present? : Bool
Stored as an Int32 bitmask.
-
#default_permissions_removed? : Bool
A node in the group tree for an authority.
-
#default_permissions_was : Int32 | Nil
A node in the group tree for an authority.
-
#default_permissions_will_change! : Nil
Include
#default_permissionsin the set of changed attributes, whether it has changed or not. -
#descendant_ids : Array(UUID)
All descendant group ids (including self) via a recursive CTE.
-
#description : String
#descriptiongetter -
#description=(value : String)
#descriptionsetter -
#description? : String | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#description_assigned? : Bool
A node in the group tree for an authority.
-
#description_change : Tuple(String | Nil, String | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#description_changed? : Bool
A node in the group tree for an authority.
-
#description_default : String
#description's default value - #description_present? : Bool
-
#description_removed? : Bool
A node in the group tree for an authority.
-
#description_was : String | Nil
A node in the group tree for an authority.
-
#description_will_change! : Nil
Include
#descriptionin the set of changed attributes, whether it has changed or not. -
#effective_features(subsystem : String) : Hash(String, JSON::Any)
Effective features for one subsystem (
{}when nothing on the path sets it). -
#effective_features : Hash(String, Hash(String, JSON::Any))
Features merged down the tree from the root to this group: for each subsystem, key by key, the deepest group that sets a key wins (a child's list replaces its parent's rather than unioning with it).
-
#feature?(subsystem : String, key : String) : Bool
Is
keytruthy in this group's effectivesubsystemfeatures? Truthy:true, a non-zero number, or a non-empty string / array / object. -
#features : Hash(String, Hash(String, JSON::Any))
#featuresgetter -
#features=(value : Hash(String, Hash(String, JSON::Any)))
#featuressetter -
#features? : Hash(String, Hash(String, JSON::Any)) | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#features_assigned? : Bool
A node in the group tree for an authority.
-
#features_change : Tuple(Hash(String, Hash(String, JSON::Any)) | Nil, Hash(String, Hash(String, JSON::Any)) | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#features_changed? : Bool
A node in the group tree for an authority.
-
#features_default : Hash(String, Hash(String, JSON::Any))
#features's default value -
#features_for(subsystem : String) : Hash(String, JSON::Any)
This group's own features for
subsystem, without inheritance. -
#features_present? : Bool
Per-subsystem feature flags / display config, keyed by subsystem code:
{"signage" => {"templates" => true, "plugins" => [...]}}. -
#features_removed? : Bool
A node in the group tree for an authority.
-
#features_was : Hash(String, Hash(String, JSON::Any)) | Nil
A node in the group tree for an authority.
-
#features_will_change! : Nil
Include
#featuresin the set of changed attributes, whether it has changed or not. -
#group_users
Direct GroupUser rows for this group.
-
#group_zones
Direct GroupZone rows for this group.
-
#history_action : String | Nil
Overrides the action recorded by the next change, e.g.
-
#history_action=(history_action : String | Nil)
Overrides the action recorded by the next change, e.g.
-
#history_correlation_id : String | Nil
A parent the change should also be found under
-
#history_metadata : PlaceOS::Model::History::Metadata | Nil
Request details recorded with changes to this record, defaults to
History.current_metadata -
#history_metadata=(history_metadata : PlaceOS::Model::History::Metadata | Nil)
Request details recorded with changes to this record, defaults to
History.current_metadata -
#id : UUID
#idgetter -
#id=(value : UUID)
#idsetter -
#id?
A node in the group tree for an authority.
-
#id_assigned? : Bool
A node in the group tree for an authority.
-
#id_change : Tuple(UUID | Nil, UUID | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#id_changed? : Bool
A node in the group tree for an authority.
-
#id_default : UUID
#id's default value - #id_present? : Bool
-
#id_removed? : Bool
A node in the group tree for an authority.
-
#id_was : UUID | Nil
A node in the group tree for an authority.
-
#id_will_change! : Nil
Include
#idin the set of changed attributes, whether it has changed or not. -
#invoke_props
A node in the group tree for an authority.
-
#name : String
#namegetter -
#name=(value : String)
#namesetter -
#name? : String | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#name_assigned? : Bool
A node in the group tree for an authority.
-
#name_change : Tuple(String | Nil, String | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#name_changed? : Bool
A node in the group tree for an authority.
-
#name_default : String
#name's default value - #name_present? : Bool
-
#name_removed? : Bool
A node in the group tree for an authority.
-
#name_was : String | Nil
A node in the group tree for an authority.
-
#name_will_change! : Nil
Include
#namein the set of changed attributes, whether it has changed or not. - #parent : Group
- #parent! : Group
- #parent=(record : Group) : Group
- #parent? : Group | Nil
-
#parent_id : UUID | Nil
#parent_idgetter -
#parent_id=(value : UUID | Nil)
#parent_idsetter -
#parent_id_assigned? : Bool
A node in the group tree for an authority.
-
#parent_id_change : Tuple(UUID | Nil | Nil, UUID | Nil | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#parent_id_changed? : Bool
A node in the group tree for an authority.
-
#parent_id_default : UUID | Nil
#parent_id's default value - #parent_id_present? : Bool
-
#parent_id_removed? : Bool
A node in the group tree for an authority.
-
#parent_id_was : UUID | Nil | Nil
A node in the group tree for an authority.
-
#parent_id_will_change! : Nil
Include
#parent_idin the set of changed attributes, whether it has changed or not. -
#persistent_attributes
A node in the group tree for an authority.
-
#primary_key
A node in the group tree for an authority.
-
#primary_key_hash
A node in the group tree for an authority.
- #reload_authority : PlaceOS::Model::Authority
- #reload_authority? : PlaceOS::Model::Authority | Nil
- #reload_parent : Group
- #reload_parent? : Group | Nil
-
#restore_attributes
Reset each attribute to their previous values and clears all changes.
-
#subsystems : Array(String)
#subsystemsgetter -
#subsystems=(value : Array(String))
#subsystemssetter -
#subsystems? : Array(String) | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#subsystems_assigned? : Bool
A node in the group tree for an authority.
-
#subsystems_change : Tuple(Array(String) | Nil, Array(String) | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#subsystems_changed? : Bool
A node in the group tree for an authority.
-
#subsystems_default : Array(String)
#subsystems's default value - #subsystems_present? : Bool
-
#subsystems_removed? : Bool
A node in the group tree for an authority.
-
#subsystems_was : Array(String) | Nil
A node in the group tree for an authority.
-
#subsystems_will_change! : Nil
Include
#subsystemsin the set of changed attributes, whether it has changed or not. -
#table_name
A node in the group tree for an authority.
-
#updated_at : Time
#updated_atgetter -
#updated_at=(value : Time)
#updated_atsetter -
#updated_at? : Time | Nil
NOTE use
getter/getter!(notproperty/property!) so that the setter defined later in__create_initializer__is the only setter on the field. -
#updated_at_assigned? : Bool
A node in the group tree for an authority.
-
#updated_at_change : Tuple(Time | Nil, Time | Nil) | Nil
Returns a Tuple of the previous and the current value of an instance variable if it has changed
-
#updated_at_changed? : Bool
A node in the group tree for an authority.
-
#updated_at_default : Time
#updated_at's default value - #updated_at_present? : Bool
-
#updated_at_removed? : Bool
A node in the group tree for an authority.
-
#updated_at_was : Time | Nil
A node in the group tree for an authority.
-
#updated_at_will_change! : Nil
Include
#updated_atin the set of changed attributes, whether it has changed or not. -
#validate_nilability
Validate that all non-nillable fields have values.
Instance methods inherited from module PlaceOS::Model::History::Tracked
change_history
change_history,
history_correlation_id : String | Nil
history_correlation_id,
history_resource_id : String
history_resource_id
Macros inherited from module PlaceOS::Model::History::Tracked
history_ignore(*fields)
history_ignore,
history_redact(*fields)
history_redact
Constructor Detail
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Deserializes the given JSON in string_or_io into
an instance of self, assuming the JSON consists
of an JSON object with key root, and whose value is
the value to deserialize. Will not deserialise from
fields with mass_assign: false
class User < ActiveModel::Model
attribute name : String
attribute google_id : UUID, mass_assign: false
end
User.from_json(%({"main": {"name": "Jason", "google_id": "f6f70bfb-c882-446d-8758-7ce47db39620"}}), root: "main") # => #<User:0x103131b20 @name="Jason">
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Serialize from a trusted JSON source
Serialize from a trusted YAML source
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Initialize PlaceOS::Model::Group from HTTP::Params.
Recreates a deleted record from its latest delete entry, keeping its id.
Records removed alongside it (cascading deletes) are not restored and redacted fields are left at their defaults. Raises if there is no delete entry or the record can't be saved, e.g. if it already exists.
Class Method Detail
Zone ids this user has any non-zero effective permission on, within
subsystem. Includes zones reached transitively (via ancestor
group membership and via ancestor zone GroupZone rows), minus
anything masked off by deny rows.
Returns a self-contained SQL subquery (single column: zone id)
yielding every zone where the user's effective permissions within any
of #subsystems satisfy required (Manage is a superset). The same
rules as .resolve_subsystem_permissions apply, but only the
per-row grant decisions are made in Crystal (bounded by the explicit
GroupUser / GroupZone rows) — the zone-subtree expansion runs
in the database via a recursive CTE, so the qualifying zone set is
never materialised in application memory. Returns nil when the user
holds no qualifying grants (callers should treat nil as an empty set).
Syncs a user's automatic group memberships with the AD groups they are
currently a member of, within #authority_id:
- the user is added to every group whose
#ad_group_mappingscontains one ofad_groups(unless they are already a member), - auto-assigned memberships (
GroupUser#auto_assignedset) are removed when the user is no longer in a mapped AD group for that group, and updated when the mapping's permissions change.
Memberships added manually (auto_assigned nil) are never modified.
When several of the user's AD groups map to the same group the
permissions are combined and the lowest AD group id is recorded.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Changefeed at row (if #id passed) or whole table level.
Returns a ChangeFeed instance which can be used to invoke async callbacks via on or
use blocking Iterator via each method.
Effective permission bitmask for (user, zone) within subsystem.
Effective permissions across a batch of zones. For every zone, the
closest applicable grant in that zone's own ancestry wins (replace
semantics — same rule as the single-zone form). Results are OR'd
across the list: this answers "what can the user do if any of
these zones is in play?". Zones with no applicable grant contribute
nothing. Returns Permissions::None for an empty list or for a
user who can't reach any of the supplied zones.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Fields not recorded, changes to only these fields are not recorded at all
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Full {zone_id => Permissions} map for the user within subsystem.
Public entry point for callers that want to resolve once and cache the
whole map (e.g. a per-request memo), instead of re-resolving per query.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Does this user have any non-zero effective permission on this zone
(directly or transitively) for subsystem?
Instance Method Detail
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
#ad_group_mappings's default value
AD group id => {display name, permissions bitmask}. Users who are members
of a mapped AD group are added to this group by .add_remove_ad_groups.
Keys are normalised (stripped + downcased) on save so matching is
case-insensitive.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #ad_group_mappings in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Assign to multiple attributes.
Assign to multiple attributes via HTTP::Params.
Assign to multiple attributes from a model object
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Assign each field from JSON if field exists in JSON and has changed in model
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Serialize attributes to JSON, without any other properties to_json may
include, as .from_json expects them.
Values are serialized as in to_json, applying any attribute converters.
Serialize attributes to JSON, without any other properties to_json may
include, as .from_json expects them.
Values are serialized as in to_json, applying any attribute converters.
Serialize attributes to JSON, without any other properties to_json may
include, as .from_json expects them.
Values are serialized as in to_json, applying any attribute converters.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #authority_id in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Serialize changed attributes to JSON as {"attribute": [previous, current]}.
Values are serialized as in to_json, applying any attribute converters.
Serialize changed attributes to JSON as {"attribute": [previous, current]}.
Values are serialized as in to_json, applying any attribute converters.
Serialize changed attributes to JSON as {"attribute": [previous, current]}.
Values are serialized as in to_json, applying any attribute converters.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #created_at in the set of changed attributes, whether it has changed or not.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Stored as an Int32 bitmask. Use permission_flags / permission_flags=
when working with the Permissions flags enum directly.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #default_permissions in the set of changed attributes, whether it has changed or not.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #description in the set of changed attributes, whether it has changed or not.
Effective features for one subsystem ({} when nothing on the path sets it).
Features merged down the tree from the root to this group: for each
subsystem, key by key, the deepest group that sets a key wins (a child's
list replaces its parent's rather than unioning with it). Uses this
group's in-memory #features, so unsaved edits are reflected.
Is key truthy in this group's effective subsystem features? Truthy:
true, a non-zero number, or a non-empty string / array / object.
Intended for server-side enforcement of features that matter beyond UI.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
This group's own features for subsystem, without inheritance.
Per-subsystem feature flags / display config, keyed by subsystem code:
{"signage" => {"templates" => true, "plugins" => [...]}}. Keys inside a
subsystem are opaque to the backend. Children inherit their ancestors'
features and may override individual keys (see #effective_features).
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #features in the set of changed attributes, whether it has changed or not.
Overrides the action recorded by the next change, e.g. approve
A parent the change should also be found under
Request details recorded with changes to this record, defaults to
History.current_metadata
Request details recorded with changes to this record, defaults to
History.current_metadata
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #id in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #name in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #parent_id in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #subsystems in the set of changed attributes, whether it has changed or not.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
NOTE use getter / getter! (not property / property!) so that the
setter defined later in __create_initializer__ is the only setter on
the field. Crystal's overload resolution silently fails to replace a
property-defined setter with one of identical signature for generic
types (e.g. Set(String)?, Array(String)?, String | Array(String)),
although it does work for non-generic ones like String?. Defining the
setter only once via __create_initializer__ ensures change tracking,
sanitization, and custom setter blocks run uniformly across all types.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Returns a Tuple of the previous and the current value of an instance variable if it has changed
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
A node in the group tree for an authority. The tree represents the
organisational hierarchy. Each group declares which subsystems
(signage, events, parking, ...) it participates in via the #subsystems
text array; subsystem-scoped permission queries are filtered against
that array. An authority may have several root groups (#parent_id nil),
each heading its own independent tree.
Include #updated_at in the set of changed attributes, whether it has changed or not.