rulesToFields function

Map<String, Object?> rulesToFields(
  1. Ability ability,
  2. String action,
  3. String subjectType
)

The values a new subject must have for action to be permitted on it.

Turns the conditions of the permitting rules into a starting object — so a user who may only create articles with status: 'draft' gets a form that already says draft, rather than one that lets them choose and then refuses.

rulesToFields(ability, 'create', 'Article');   // {'status': 'draft'}

Only plain values are taken. A condition like {views: {$gte: 100}} describes a range rather than a value, and inventing one would be a guess presented to the user as a fact. Forbidding rules are skipped for the same reason: they say what is not allowed, which is not a default.

Implementation

Map<String, Object?> rulesToFields(
  Ability ability,
  String action,
  String subjectType,
) {
  final fields = <String, Object?>{};

  for (final rule in ability.rulesFor(action, subjectType)) {
    final conditions = rule.origin.conditions;
    if (rule.inverted || conditions == null) continue;

    for (final entry in conditions.entries) {
      // A nested map is an operator query, not a value.
      if (entry.value is Map) continue;
      _setByPath(fields, entry.key, entry.value);
    }
  }

  return fields;
}