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

  • 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