Class: Moderate::Flag
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Moderate::Flag
- Defined in:
- lib/moderate/models/flag.rb
Overview
A system/auto-filter flag: the record an adapter (or a manual action) leaves behind when content is flagged for review rather than rejected outright.
Flags are what ‘:flag`-mode filtering produces AFTER COMMIT — the write succeeds, then a Flag lands in the queue. This is intentional and load-bearing: a flag must NEVER be created inside a validator/transaction, because a validator is supposed to be side-effect-free and a Flag written inside a transaction that later rolls back would silently vanish (you’d “moderate” content that was never saved). The Filterable concern enforces the after_commit timing; this model is just the record + the queue + the “content flagged” notification.
The same ‘pending` scope serves BOTH a human admin queue and an automated consumer (e.g. a job that auto-actions high-confidence flags), so the gem doesn’t presume a human is the only reviewer.
Constant Summary collapse
- STATUSES =
%w[pending actioned dismissed].freeze
- SOURCES =
Built-in/generic source names. Host-registered adapter names are also valid sources (see ‘.sources` below) because `Moderate.classify` stamps the adapter name onto the Result when the adapter does not set one explicitly. This is why a host can register `:openai` or `:image` and see that exact name in the queue.
%w[text_filter image_filter external_classifier manual].freeze
- MODES =
What the flag WOULD do. ‘:flag` allowed the write and queued it; `:block` rejected the write (a block-mode trip can also be recorded as a flag for the audit trail). Validated by the model (inclusion), not a DB constraint.
%w[flag block].freeze
Class Method Summary collapse
-
.flag!(flaggable:, field:, owner:, source:, mode:, excerpt:, categories:, scores:, context:) ⇒ Object
The single entry point the Filterable concern uses to file a flag.
- .sources ⇒ Object
Instance Method Summary collapse
- #closed? ⇒ Boolean
-
#flaggable_label ⇒ Object
A label for the flagged thing in the queue.
- #pending? ⇒ Boolean
Class Method Details
.flag!(flaggable:, field:, owner:, source:, mode:, excerpt:, categories:, scores:, context:) ⇒ Object
The single entry point the Filterable concern uses to file a flag. Centralizes coercion (categories → Array, scores/context → Hash) so callers can hand us whatever shape a Moderate::Result exposed without each one re-normalizing. ‘context` is freeform JSON for audit (which policy fired, the raw classifier payload, etc.) — never relied on by the gem’s own logic.
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/moderate/models/flag.rb', line 74 def self.flag!(flaggable:, field:, owner:, source:, mode:, excerpt:, categories:, scores:, context:) create!( flaggable: flaggable, field: field, owner: owner, source: source, mode: mode, excerpt: excerpt, categories: Array(categories), scores: scores.to_h, context: context.to_h ) end |
Instance Method Details
#closed? ⇒ Boolean
96 97 98 |
# File 'lib/moderate/models/flag.rb', line 96 def closed? status.in?(%w[actioned dismissed]) end |
#flaggable_label ⇒ Object
A label for the flagged thing in the queue. Asks the flaggable for its own ‘moderation_label` (Moderate::Reportable interface); falls back to a generic “Type id” string for content that doesn’t implement it.
103 104 105 106 107 |
# File 'lib/moderate/models/flag.rb', line 103 def flaggable_label return flaggable.moderation_label if flaggable.respond_to?(:moderation_label) "#{flaggable_type} #{flaggable_id}" end |
#pending? ⇒ Boolean
92 93 94 |
# File 'lib/moderate/models/flag.rb', line 92 def pending? status == "pending" end |