Class: Card::Action
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Card::Action
- Extended by:
- Admin
- Includes:
- Differ
- Defined in:
- mod/history/lib/card/action.rb,
mod/history/lib/card/action/admin.rb,
mod/history/lib/card/action/differ.rb,
mod/history/lib/card/action/action_renderer.rb
Overview
An action is a group of changes to a single card that is recorded during an act. Together, acts, actions, and changes comprise a comprehensive card history tracking system.
For example, if a given web submission changes both the name and type of a given card, that would be recorded as one action with two changes. If there are multiple cards changed, each card would have its own action, but the whole submission would still comprise just one single act.
An Action records:
Defined Under Namespace
Modules: Admin, Differ Classes: ActionRenderer
Constant Summary collapse
- TYPE_OPTIONS =
these are the three possible values for action_type
%i[create update delete].freeze
Class Method Summary collapse
- .all_viewable ⇒ Object
- .all_with_cards ⇒ Object
-
.cache ⇒ Card::Cache
cache object for actions.
-
.fetch(id) ⇒ Action?
retrieve action from cache if available.
Instance Method Summary collapse
-
#action_type ⇒ Symbol
retrieve action_type (create, update, or delete).
-
#action_type=(value) ⇒ Integer
assign action_type (create, update, or delete).
- #all_changes ⇒ Object
-
#card ⇒ Card
each action is associated with on and only one card.
-
#change(field) ⇒ Change
action's Change object for given field.
-
#changed_values ⇒ Object
all changed values in hash form.
-
#changes ⇒ Hash
all action changes in hash form.
- #current_changes ⇒ Hash
-
#expire ⇒ Object
remove action from action cache.
-
#interpret_field(field) ⇒ Symbol
translate field into fieldname as referred to in database.
-
#interpret_value(field, value) ⇒ Integer, ...
value in form prescribed for specific field name.
- #previous_action ⇒ Object
-
#previous_change(field) ⇒ Change
most recent change to given field before this one.
-
#previous_value(field) ⇒ Object
value of field set by most recent Change before this one.
- #sole? ⇒ Boolean
-
#value(field) ⇒ Object
value set by action's Change to given field.
Methods included from Admin
delete_cardless, delete_changeless, delete_old, make_current_state_the_initial_state
Methods included from Differ
#cardtype_diff, #content_diff, #green?, #name_diff, #new_content?, #new_name?, #new_type?, #raw_view, #red?, #summary_diff_omits_content?
Class Method Details
.all_viewable ⇒ Object
65 66 67 |
# File 'mod/history/lib/card/action.rb', line 65 def all_viewable all_with_cards.where Query::CardQuery.viewable_sql end |
.all_with_cards ⇒ Object
61 62 63 |
# File 'mod/history/lib/card/action.rb', line 61 def all_with_cards joins :ar_card end |
.cache ⇒ Card::Cache
cache object for actions
57 58 59 |
# File 'mod/history/lib/card/action.rb', line 57 def cache Card::Cache[Action] end |
.fetch(id) ⇒ Action?
retrieve action from cache if available
49 50 51 52 53 |
# File 'mod/history/lib/card/action.rb', line 49 def fetch id cache.fetch id.to_s do find id.to_i end end |
Instance Method Details
#action_type ⇒ Symbol
retrieve action_type (create, update, or delete)
107 108 109 110 |
# File 'mod/history/lib/card/action.rb', line 107 def action_type return :draft if draft TYPE_OPTIONS[read_attribute(:action_type)] end |
#action_type=(value) ⇒ Integer
assign action_type (create, update, or delete)
101 102 103 |
# File 'mod/history/lib/card/action.rb', line 101 def action_type= value write_attribute :action_type, TYPE_OPTIONS.index(value) end |
#all_changes ⇒ Object
154 155 156 157 158 |
# File 'mod/history/lib/card/action.rb', line 154 def all_changes self.class.cache.fetch("#{id}-changes") do card_changes.find_all.to_a end end |
#card ⇒ Card
each action is associated with on and only one card
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'mod/history/lib/card/action.rb', line 72 def card Card.fetch card_id, look_in_trash: true # I'm not sure what the rationale for the following was/is, but it was causing # problems in cases where slot attributes are overridden (eg see #wrap_data in # sources on wikirate). The problem is the format object had the set modules but # the card didn't. # # My guess is that the need for the following had something to do with errors # associated with changed types. If so, the solution probably needs to handling # including the set modules associated with the type at the time of the action # rather than including no set modules at all. # # What's more, we _definitely_ don't want to hard code special behavior for # specific types in here! # , skip_modules: true # return res unless res && res.type_id.in?([FileID, ImageID]) # res.include_set_modules end |
#change(field) ⇒ Change
action's Change object for given field
136 137 138 |
# File 'mod/history/lib/card/action.rb', line 136 def change field changes[interpret_field field] end |
#changed_values ⇒ Object
all changed values in hash form. { field1: new_value }
174 175 176 177 178 |
# File 'mod/history/lib/card/action.rb', line 174 def changed_values @changed_values ||= changes.each_with_object({}) do |(key,change), h| h[key] = change.value end end |
#changes ⇒ Hash
all action changes in hash form. { field1: Change1 }
162 163 164 165 166 167 168 169 170 171 |
# File 'mod/history/lib/card/action.rb', line 162 def changes @changes ||= if sole? current_changes else all_changes.each_with_object({}) do |change, hash| hash[change.field.to_sym] = change end end end |
#current_changes ⇒ Hash
181 182 183 184 185 186 187 188 189 |
# File 'mod/history/lib/card/action.rb', line 181 def current_changes return {} unless card @current_changes ||= Card::Change::TRACKED_FIELDS.each_with_object({}) do |field, hash| hash[field.to_sym] = Card::Change.new field: field, value: card.send(field), card_action_id: id end end |
#expire ⇒ Object
remove action from action cache
94 95 96 |
# File 'mod/history/lib/card/action.rb', line 94 def expire self.class.cache.delete id.to_s end |
#interpret_field(field) ⇒ Symbol
translate field into fieldname as referred to in database
196 197 198 199 200 201 202 |
# File 'mod/history/lib/card/action.rb', line 196 def interpret_field field case field when :content then :db_content when :cardtype then :type_id else field.to_sym end end |
#interpret_value(field, value) ⇒ Integer, ...
value in form prescribed for specific field name
209 210 211 212 213 214 215 216 217 218 |
# File 'mod/history/lib/card/action.rb', line 209 def interpret_value field, value case field.to_sym when :type_id value && value.to_i when :cardtype type_card = value && Card.quick_fetch(value.to_i) type_card && type_card.name.capitalize else value end end |
#previous_action ⇒ Object
112 113 114 |
# File 'mod/history/lib/card/action.rb', line 112 def previous_action Card::Action.where("id < ? AND card_id = ?", id, card_id).last end |
#previous_change(field) ⇒ Change
most recent change to given field before this one
143 144 145 146 147 148 149 150 151 152 |
# File 'mod/history/lib/card/action.rb', line 143 def previous_change field return nil if action_type == :create field = interpret_field field if @previous_changes && @previous_changes.key?(field) @previous_changes[field] else @previous_changes ||= {} @previous_changes[field] = card.last_change_on field, before: self end end |
#previous_value(field) ⇒ Object
value of field set by most recent Change before this one
127 128 129 130 131 |
# File 'mod/history/lib/card/action.rb', line 127 def previous_value field return if action_type == :create return unless (previous_change = previous_change field) interpret_value field, previous_change.value end |
#sole? ⇒ Boolean
220 221 222 223 |
# File 'mod/history/lib/card/action.rb', line 220 def sole? all_changes.empty? && (action_type == :create || Card::Action.where(card_id: card_id).count == 1) end |
#value(field) ⇒ Object
value set by action's Change to given field
119 120 121 122 |
# File 'mod/history/lib/card/action.rb', line 119 def value field return unless (change = change field) interpret_value field, change.value end |