Class: Collavre::Creatives::RevealPathResolver

Inherits:
Object
  • Object
show all
Defined in:
app/services/collavre/creatives/reveal_path_resolver.rb

Overview

Resolves, for each flat-search hit that is only reachable through a linked creative shell, the path of node ids to expand *in the signed-in user’s own tree* to surface that shell — ordered root-most ancestor down to the shell itself.

Why this exists: search breadcrumbs (BreadcrumbResolver) carry the hit’s origin-space ancestors. When a shared subtree is represented by a shell nested under one of the user’s own folders, those origin ancestors never include the local folder that contains the shell, so the picker’s breadcrumb-jump cannot expand down to it (the shell <li> is never rendered and ‘_findItem` returns null). This service supplies the missing user-local prefix `[localFolder…, shellId]`; the client expands it before walking the origin chain. Display is unaffected — only navigation.

Returns { hit_id (Integer) => { origin_ancestor_id (Integer) => [user_tree_id, …] } }, i.e. for each hit, a per-origin-ancestor map: every origin ancestor (incl. the hit itself) that the user holds a renderable shell for maps to the local path that surfaces that shell. The client anchors a breadcrumb click at the entry at/above the clicked crumb, so a higher ancestor crumb resolves through its own shell rather than a deeper one (a user may hold shells at several depths of the same shared subtree). Hits not routed through any shell are omitted (their origin path already matches rendered ids).

Instance Method Summary collapse

Constructor Details

#initialize(creative_ids, user: nil, include_archived: false) ⇒ RevealPathResolver

Returns a new instance of RevealPathResolver.



26
27
28
29
30
# File 'app/services/collavre/creatives/reveal_path_resolver.rb', line 26

def initialize(creative_ids, user: nil, include_archived: false)
  @ids = Array(creative_ids).map { |id| id.to_s.to_i }.uniq.reject(&:zero?)
  @user = user
  @include_archived = include_archived
end

Instance Method Details

#callObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/services/collavre/creatives/reveal_path_resolver.rb', line 32

def call
  return {} if @ids.empty? || user.nil?

  # Origin-space self+ancestor rows for every hit (generations 0 = self).
  hit_rows = CreativeHierarchy
    .where(descendant_id: @ids)
    .pluck(:descendant_id, :ancestor_id, :generations)
  return {} if hit_rows.empty?

  shells_by_origin = user_shells_by_origin(hit_rows.map { |_d, a, _g| a }.uniq)
  return {} if shells_by_origin.empty?

  local_prefix = local_ancestor_paths(shells_by_origin.values.flatten.uniq)

  # For each hit, map every origin ancestor (incl. self) that has a renderable
  # user shell to the local path [localFolder..., shellId] surfacing it.
  hit_rows.group_by { |descendant_id, _a, _g| descendant_id }
    .each_with_object({}) do |(hit_id, rows), out|
      paths = rows.each_with_object({}) do |(_d, ancestor_id, _g), acc|
        next if acc.key?(ancestor_id)

        shell_ids = shells_by_origin[ancestor_id]
        next unless shell_ids

        # A user may hold several shells for the same origin; pick the first
        # whose local path is actually renderable (not behind an archived
        # folder; [] for a root shell counts as renderable).
        shell_id = shell_ids.find { |sid| local_prefix[sid] }
        next unless shell_id

        acc[ancestor_id] = local_prefix[shell_id] + [ shell_id ]
      end
      out[hit_id] = paths if paths.any?
    end
end