Skip to content

Extract row-building from EffortWithLapSplitRows so subclasses stop bypassing its constructor #2232

Description

@moveson

Problem

Two view models inherit from EffortWithLapSplitRows for implementation reuse (the lap_split_rows machinery, related_split_times, method_missing delegation to the effort) while deliberately refusing the parent's construction protocol, each carrying an inline Lint/MissingSuper disable:

  • app/view_models/plan_display.rb:12 — built from a course and params; there is no persisted effort, so the parent's post_initializevalidate_setup (raises without an effort) → load_effort (re-queries via ranking_subquery) is inapplicable. Its "effort" is a new unsaved record whose split times come from the projection engine.
  • app/view_models/effort_place_view.rb:7 — takes an effort but assigns effort.with_rank directly, skipping the parent's load_effort reload and validate_setup.

Calling super in either would raise or run a meaningless query, so the omissions are intentional — but the cop is pointing at a real smell: these are not is-a relationships. A pacing plan is not an effort-with-rows; it borrows the row-building.

Proposal

Extract the shared machinery (lap_split_rows / rows_from_lap_splits, related_split_times, ordered/indexed split time helpers, effort delegation) into a module (or compose an instance) that EffortWithLapSplitRows, PlanDisplay, and EffortPlaceView all use. Each class then owns an honest constructor, and both rubocop:disable Lint/MissingSuper annotations go away.

Worth checking while in there: EffortAnalysisView also subclasses EffortWithLapSplitRows with its own load_effort override — it may want the same treatment for consistency, even though it currently participates in the parent's constructor.

Noticed while implementing #2229 (see discussion on the PlanDisplay changes in #2231); deliberately kept out of that PR's scope.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions