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.



114
115
116
117
118
119
120
# File 'lib/stagehand/staging/checklist.rb', line 114

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, priority: [:delete, :update, :insert]) ⇒ Object

Returns a list of entries that only includes a single entry for each record. The entries are prioritized by the list of operations as given by ‘:priority`.



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

def self.compact_entries(entries, priority: [:delete, :update, :insert])
  compact_entries = group_entries(entries)
  compact_entries = compact_entries.values_at(*priority).flatten
  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_base_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



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/stagehand/staging/checklist.rb', line 152

def affected_entries
  cache(:affected_entries) do
    from_subject = subject_entries
    from_subject |= CommitEntry.where(commit_id: subject_entries.select(:commit_id))
    related = self.class.related_entries(from_subject, @relation_filter)
    associated = self.class.associated_records(related, @association_filter)
    associated_related = self.class.related_entries(associated, @relation_filter)

    (from_subject + related + associated_related).uniq
  end
end

#affected_recordsObject



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

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

#confirm_createObject



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

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

#confirm_deleteObject



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

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

#confirm_updateObject



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

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



140
141
142
# File 'lib/stagehand/staging/checklist.rb', line 140

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)


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

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

#subject_entriesObject



164
165
166
# File 'lib/stagehand/staging/checklist.rb', line 164

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

#syncing_entriesObject



144
145
146
# File 'lib/stagehand/staging/checklist.rb', line 144

def syncing_entries
  cache(:syncing_entries) { self.class.compact_entries(affected_entries, priority: Synchronizer::ENTRY_SYNC_ORDER) }
end