Class: Stagehand::Staging::Checklist

Inherits:
Object
  • Object
show all
Extended by:
Cache
Includes:
Cache
Defined in:
lib/stagehand/staging/checklist.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Cache

cache

Constructor Details

#initialize(subject, confirmation_filter: Configuration.checklist_confirmation_filter, association_filter: Configuration.checklist_association_filter, relation_filter: Configuration.checklist_relation_filter) ⇒ Checklist

Returns a new instance of Checklist.



101
102
103
104
105
106
107
# File 'lib/stagehand/staging/checklist.rb', line 101

def initialize(subject, confirmation_filter: Configuration.checklist_confirmation_filter, association_filter: Configuration.checklist_association_filter, relation_filter: Configuration.checklist_relation_filter)
  @subject = subject
  @confirmation_filter = confirmation_filter
  @association_filter = association_filter
  @relation_filter = relation_filter
  affected_entries # Init the affected_entries changes can be rolled back without affecting the checklist
end

Class Method Details

.associated_records(entries, association_filter = nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/stagehand/staging/checklist.rb', line 42

def self.associated_records(entries, association_filter = nil)
  records = preload_records(compact_entries(entries)).select(&:record).flat_map do |entry|
    associated_associations(entry.record_class).flat_map do |association|
      entry.record.send(association)
    end
  end

  records.uniq!
  records.compact!
  records.select! {|record| stagehand_class?(record.class) }
  records.select!(&association_filter) if association_filter

  return records
end

.compact_entries(entries) ⇒ Object

Returns a list of entries that only includes a single entry for each record. The type of entry chosen prioritizes creates over updates, and deletes over creates.



59
60
61
62
63
64
65
# File 'lib/stagehand/staging/checklist.rb', line 59

def self.compact_entries(entries)
  compact_entries = group_entries(entries)
  compact_entries = compact_entries[:delete] + compact_entries[:insert] + compact_entries[:update]
  compact_entries.uniq!(&:key)

  return compact_entries
end

.group_entries(entries) ⇒ Object

Groups entries by their operation



68
69
70
71
72
73
# File 'lib/stagehand/staging/checklist.rb', line 68

def self.group_entries(entries)
  group_entries = Hash.new {|h,k| h[k] = [] }
  group_entries.merge! entries.group_by(&:operation).symbolize_keys!

  return group_entries
end

.preload_records(entries) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/stagehand/staging/checklist.rb', line 75

def self.preload_records(entries)
  entries.group_by(&:table_name).each do |table_name, group_entries|
    klass = CommitEntry.infer_class(table_name)
    records = klass.where(:id => group_entries.collect(&:record_id))
    records = records.includes(associated_associations(klass))
    records_by_id = records.collect {|r| [r.id, r] }.to_h
    group_entries.each do |entry|
      entry.record = records_by_id[entry.record_id]
    end
  end

  return entries
end


11
12
13
# File 'lib/stagehand/staging/checklist.rb', line 11

def self.related_commit_ids(commit)
  related_entries(commit.entries).collect(&:commit_id).select(&:present?).uniq
end


7
8
9
# File 'lib/stagehand/staging/checklist.rb', line 7

def self.related_commits(commit)
  Commit.find(related_commit_ids(commit))
end


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/stagehand/staging/checklist.rb', line 15

def self.related_entries(entries, relation_filter = nil)
  entries = Array.wrap(entries)
  related_entries = []

  entries_to_spider = Array.wrap(entries)
  while entries_to_spider.present?
    contained_matching = CommitEntry.contained.matching(entries_to_spider)
    contained_matching = contained_matching.where(id: contained_matching.select(&relation_filter)) if relation_filter

    matching_commit_entries = CommitEntry.where(:commit_id => contained_matching.select(:commit_id))

    # Spider using content operations. Don't spider control operations to avoid extending the list of results unnecessarily
    content_operations, control_operations = matching_commit_entries.partition(&:content_operation?)
    entries_to_spider = content_operations - related_entries

    # Record the spidered entries and the control entries
    related_entries.concat(entries_to_spider)
    related_entries.concat(control_operations)
  end

  # Also include uncontained commit entries that matched
  related_entries.concat(CommitEntry.uncontained.matching(entries + related_entries))
  related_entries.uniq!

  return related_entries
end

Instance Method Details

#affected_entriesObject



139
140
141
142
143
144
145
146
147
# File 'lib/stagehand/staging/checklist.rb', line 139

def affected_entries
  cache(:affected_entries) do
    related = self.class.related_entries(@subject, @relation_filter)
    associated = self.class.associated_records(related, @association_filter)
    associated_related = self.class.related_entries(associated, @relation_filter)

    (related + associated_related).uniq
  end
end

#affected_recordsObject



135
136
137
# File 'lib/stagehand/staging/checklist.rb', line 135

def affected_records
  cache(:affected_records) { affected_entries.uniq(&:key).collect(&:record).compact }
end

#confirm_createObject



109
110
111
# File 'lib/stagehand/staging/checklist.rb', line 109

def confirm_create
  cache(:confirm_create) { grouped_required_confirmation_entries[:insert].collect(&:record) }
end

#confirm_deleteObject



113
114
115
# File 'lib/stagehand/staging/checklist.rb', line 113

def confirm_delete
  cache(:confirm_delete) { grouped_required_confirmation_entries[:delete].collect(&:record).compact }
end

#confirm_updateObject



117
118
119
# File 'lib/stagehand/staging/checklist.rb', line 117

def confirm_update
  cache(:confirm_update) { grouped_required_confirmation_entries[:update].collect(&:record) }
end

#requires_confirmationObject

Returns a list of records that exist in commits where the staging_record is not in the start operation



127
128
129
# File 'lib/stagehand/staging/checklist.rb', line 127

def requires_confirmation
  cache(:requires_confirmation) { grouped_required_confirmation_entries.values.flatten.collect(&:record).compact }
end

#requires_confirmation?Boolean

Returns true if there are any changes in the checklist that require confirmation

Returns:

  • (Boolean)


122
123
124
# File 'lib/stagehand/staging/checklist.rb', line 122

def requires_confirmation?
  cache(:requires_confirmation?) { grouped_required_confirmation_entries.values.flatten.present? }
end

#subject_entriesObject



149
150
151
# File 'lib/stagehand/staging/checklist.rb', line 149

def subject_entries
  cache(:subject_entries) { CommitEntry.matching(@subject) }
end

#syncing_entriesObject



131
132
133
# File 'lib/stagehand/staging/checklist.rb', line 131

def syncing_entries
  cache(:syncing_entries) { self.class.compact_entries(affected_entries) }
end