class Card::Act
An “act” is a group of recorded {Card::Action actions} on {Card cards}. Together, {Act acts}, {Action actions}, and {Change changes} comprise a comprehensive {Card card} history tracking system.
For example, if a given web form submissions updates the contents of three cards, then the submission will result in the recording of three {Action actions}, each of which is tied to one {Act act}.
Each act records:
-
the actor_id (an id associated with the account responsible)
-
the card_id of the act's primary card
-
acted_at, a timestamp of the action
-
the ip_address of the actor where applicable.
Public Class Methods
all acts with actions that current user has permission to view @return [ActiveRecord Relation]
# File lib/card/act.rb, line 53 def all_viewable action_where=nil relation = joins(ar_actions: :ar_card) relation = relation.where(action_where) if action_where relation.where(Query::CardQuery.viewable_sql).where.not(card_id: nil).distinct end
all acts with actions on a given list of cards @param card_ids [Array of Integers] @param with_drafts [true, false] (only shows drafts of current user) @return [Array of Acts]
# File lib/card/act.rb, line 45 def all_with_actions_on card_ids, with_drafts=false sql = "card_actions.card_id IN (:card_ids) AND (draft is not true" sql << (with_drafts ? " OR actor_id = :user_id)" : ")") all_viewable([sql, { card_ids: card_ids, user_id: Card::Auth.current_id }]) end
# File lib/card/act.rb, line 59 def cache Card::Cache[Card::Act] end
remove all acts that have no action. (janitorial)
# File lib/card/act.rb, line 33 def delete_actionless joins( "LEFT JOIN card_actions ON card_acts.id = card_act_id" ).where( "card_actions.id is null" ).delete_all end
remove all acts that have no card. (janitorial)
CAREFUL - could still have actions even if act card is gone…
# File lib/card/act.rb, line 27 def delete_cardless left_join = "LEFT JOIN cards ON card_acts.card_id = cards.id" joins(left_join).where("cards.id IS NULL").delete_all end
used by rails time_ago timestamp is set by rails on create
# File lib/card/act.rb, line 65 def timestamp_attributes_for_create super << "acted_at" end
Public Instance Methods
act's action on the card in question @param card_id [Integer] @return [Card::Action]
# File lib/card/act.rb, line 97 def action_on card_id actions.find do |action| action.card_id == card_id && !action.draft end end
list of all actions that are part of the act @return [Array]
# File lib/card/act.rb, line 88 def actions cached=true return ar_actions unless cached self.class.cache.fetch("#{id}-actions") { ar_actions.find_all.to_a } end
act's actions on either the card itself or another card that includes it @param card [Card] @return [Array of Actions]
# File lib/card/act.rb, line 122 def actions_affecting card actions.select do |action| (card.id == action.card_id) || card.nestee_ids.include?(action.card_id) end end
# File lib/card/act.rb, line 70 def actor Card.fetch actor_id end
the act's primary card @return [Card]
# File lib/card/act.rb, line 76 def card Card.fetch card_id, look_in_trash: true # , skip_modules: true # FIXME: if the following is necessary, we need to document why. # generally it's a very bad idea to have type-specific code here. # return res unless res&.type_id&.in?([Card::FileID, Card::ImageID]) # res.include_set_modules end
# File lib/card/act.rb, line 109 def draft? main_action&.draft end
time (in words) since act took place @return [String]
# File lib/card/act.rb, line 115 def elapsed_time DateTime.new(acted_at).distance_of_time_in_words_to_now end
act's action on primary card if it exists. otherwise act's first action @return [Card::Action]
# File lib/card/act.rb, line 105 def main_action action_on(card_id) || actions.first end
Private Instance Methods
used by before filter
# File lib/card/act.rb, line 132 def assign_actor self.actor_id ||= Auth.current_id end