Module: Moderate::EngineHelper

Defined in:
app/helpers/moderate/engine_helper.rb

Overview

View helpers exposed to BOTH the engine’s own views and the HOST app’s views.

The headline helper is ‘moderate_report_link` (and its terser alias `report_link`): a one-liner you drop next to any reportable piece of content to render an in-app “Report” affordance — the exact thing Apple Guideline 1.2 and Google Play’s UGC policy require every social/UGC app to surface next to user-generated content.

- https://developer.apple.com/app-store/review/guidelines/#user-generated-content
- https://support.google.com/googleplay/android-developer/answer/9876937

GOTCHA — isolated engine + host views: ‘Moderate::Engine` is an isolated engine (`isolate_namespace Moderate`). Rails does NOT auto-include an isolated engine’s helpers into the host application’s views — that’s the whole point of isolation. But ‘moderate_report_link` is meant to be called from the host’s own templates (e.g. ‘<%= moderate_report_link(@comment, field: :body) %>`), so we explicitly mix this module into ActionView for the host at load time via the `ActiveSupport.on_load(:action_view)` hook at the bottom of this file. That is the same trick Devise uses to expose its url helpers app-wide.

Instance Method Summary collapse

Instance Method Details

Render an in-app report affordance for ‘record`’s ‘field`, or NOTHING when the current viewer isn’t allowed to report it.

Renders nothing (returns nil) — deliberately, and in three cases:

1. there is no signed-in viewer (anonymous users use the public DSA notice
   form instead; this is the *in-app* button), or
2. the record doesn't know how to be reported (no `report_visible_to?`), or
3. the record says this viewer may not report this field
   (`record.report_visible_to?(viewer, field:)` is false — e.g. you can't
   report your own content, or content you can't even see).

This “render nothing unless permitted” contract is what lets a host sprinkle the helper liberally across a template without guarding each call site — the helper is the guard. It mirrors the reference app’s ‘report_link`.

Parameters:

  • record (Object)

    any model that ‘include`s Moderate::Reportable

  • field (Symbol, String, nil) (defaults to: nil)

    which field is being reported (nil => the whole record). Passed straight through to the visibility check and the intake form so the moderator sees exactly which field was flagged.

  • label (String, nil) (defaults to: nil)

    the visible link text. Defaults to a translated “Report” string so the host gets i18n for free.

  • html_options (Hash)

    extra HTML attributes merged onto the <a> (class, data-*, aria-*, …) so the host can style it to taste without a wrapper.

Returns:

  • (ActiveSupport::SafeBuffer, nil)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/helpers/moderate/engine_helper.rb', line 47

def moderate_report_link(record, field: nil, label: nil, **html_options)
  viewer = moderate_current_viewer
  return if viewer.nil?

  # The record gates its own reportability. We `respond_to?`-guard so a host can
  # pass any object without the helper exploding — a non-reportable object simply
  # renders nothing, same as "not permitted".
  return unless record.respond_to?(:report_visible_to?)
  return unless record.report_visible_to?(viewer, field: field)

  label ||= moderate_report_default_label
  link_to(label, moderate_report_path_for(record, field: field), **html_options)
end

Terse alias. The README/docs use ‘moderate_report_link` in host views (to avoid clashing with a host’s own ‘report_link`), but `report_link` reads cleanest inside the engine’s own templates. Same method, two names.



64
65
66
# File 'app/helpers/moderate/engine_helper.rb', line 64

def report_link(record, field: nil, label: nil, **html_options)
  moderate_report_link(record, field: field, label: label, **html_options)
end