Module: OpenLoam::Bulk
- Defined in:
- lib/open_loam/bulk.rb
Overview
Datatable bulk actions over selected records — policy-checked PER record and
tenant-scoped. The ids are resolved THROUGH the tenant scope
(model.where(id: ids)), so a forged cross-tenant id is simply not found —
a bulk op can never reach another tenant's rows.
OpenLoam::Bulk.soft_delete(Equipment, params[:ids])
OpenLoam::Bulk.set_field(Equipment, params[:ids], field: "status", value: "retired")
Returns the number of records actually affected (a record the actor may not touch, or an id from another tenant, is silently skipped).
Class Method Summary collapse
- .each_permitted(model, ids) ⇒ Object
-
.selected(model, ids) ⇒ Object
A relation for "export selected" — tenant-scoped, so it composes with OpenLoam::Export.csv and can't leak another tenant's rows.
- .set_field(model, ids, field:, value:) ⇒ Object
- .soft_delete(model, ids) ⇒ Object
-
.workflow_column?(model, field) ⇒ Boolean
A workflow status column may ONLY change through a transition (role-gated).
- .writable_column?(model, field) ⇒ Boolean
Class Method Details
.each_permitted(model, ids) ⇒ Object
40 41 42 43 44 45 46 |
# File 'lib/open_loam/bulk.rb', line 40 def each_permitted(model, ids) count = 0 selected(model, ids).find_each do |record| count += 1 if yield(record, OpenLoam::Policy.for(record)) end count end |
.selected(model, ids) ⇒ Object
A relation for "export selected" — tenant-scoped, so it composes with OpenLoam::Export.csv and can't leak another tenant's rows.
36 37 38 |
# File 'lib/open_loam/bulk.rb', line 36 def selected(model, ids) model.where(id: Array(ids)) end |
.set_field(model, ids, field:, value:) ⇒ Object
24 25 26 27 28 29 30 31 32 |
# File 'lib/open_loam/bulk.rb', line 24 def set_field(model, ids, field:, value:) field = field.to_s each_permitted(model, ids) do |record, policy| next unless policy.update? && policy.writable?(field) && writable_column?(model, field) record.update!(field => value) true end end |
.soft_delete(model, ids) ⇒ Object
15 16 17 18 19 20 21 22 |
# File 'lib/open_loam/bulk.rb', line 15 def soft_delete(model, ids) each_permitted(model, ids) do |record, policy| next unless policy.destroy? record.soft_delete! true end end |
.workflow_column?(model, field) ⇒ Boolean
A workflow status column may ONLY change through a transition (role-gated). Skip it here so a bulk set-field can't self-"approve" (the model guard is the backstop; this keeps the bulk op a clean no-op rather than an error).
55 56 57 |
# File 'lib/open_loam/bulk.rb', line 55 def workflow_column?(model, field) model.respond_to?(:open_loam_workflow) && model.open_loam_workflow&.column == field end |