module Card::Director::CardClass

director-related Card class methods

Public Instance Methods

create(opts) click to toggle source
# File lib/card/director/card_class.rb, line 11
def create opts
  card = new opts
  card.save
  card
end
create!(opts) click to toggle source
# File lib/card/director/card_class.rb, line 5
def create! opts
  card = new opts
  card.save!
  card
end
ensure(opts) click to toggle source

The ensure methods are use to make sure a card exists and can be used when you’re unsure as to whether it already does. It’s arguments are largely the same as those used by {#create Card#create} and {Director::All#update @card.update} with the important exception of ‘conflict`.

The conflict argument takes one of three values:

- **defer**: let existing card stay as it is
- **default**: update existing card if it is "pristine" (meaning it has not
  been edited by anyone other than Decko Bot)
- **override**: update existing card

If the options specify a codename and the name is already in use, things get a little more involved. (Note: we MUST ensure that a card with the codename exists!)

If the conflict setting is “defer”:

- if the _codename_ is NOT already in use, we create a new card with an
  altered name
- otherwise we do nothing.

If the conflict setting is “default”:

- if the _codename_ is NOT already in use:
  - if the card using the name we want is pristine, we update that card
  - otherwise we create a new card with an altered name
- if the _codename_ IS already in use
  - if the card with the codename is pristine, we update everything but the
    name (which is used by another card)
  - otherwise we do nothing

If the conflict setting is “override”:

- if the _codename_ is NOT already in use, we update the existing card with the
  name.
- otherwise we alter the card withe the conflicting name and update the card
  with the codename.
# File lib/card/director/card_class.rb, line 54
def ensure opts
  ensuring opts, &:save_if_needed
end
ensure!(opts) click to toggle source
# File lib/card/director/card_class.rb, line 58
def ensure! opts
  ensuring opts, &:save_if_needed!
end

Private Instance Methods

ensure_advanced_default(card, other, opts) click to toggle source
# File lib/card/director/card_class.rb, line 142
def ensure_advanced_default card, other, opts
  return unless card.pristine?

  if card.new? && other.pristine?
    other.assign_attributes opts
    other
  else
    ensure_non_conflicting_name card
  end
end
ensure_advanced_defer(card, other, _opts) click to toggle source
# File lib/card/director/card_class.rb, line 135
def ensure_advanced_defer card, other, _opts
  return unless card.new? # codenamed card doesn't exist yet

  card.name = other.name.alternative
  card
end
ensure_advanced_override(card, other, opts) click to toggle source
# File lib/card/director/card_class.rb, line 153
def ensure_advanced_override card, other, opts
  if card.new?
    other.assign_attributes opts
    other
  else
    other.name = other.name.alternative
    other.save
    card.skip_event! :validate_renaming # so that type and content can also change
    card
  end
end
ensure_non_conflicting_name(card) click to toggle source
# File lib/card/director/card_class.rb, line 165
def ensure_non_conflicting_name card
  card.name = card.new? ? card.name.alternative : card.name_before_act
  card
end
ensure_purity_advanced(card, other, opts) { |attempt_card, true| ... } click to toggle source
# File lib/card/director/card_class.rb, line 118
def ensure_purity_advanced card, other, opts
  attempt_card = send "ensure_advanced_#{@conflict_mode}", card, other, opts
  attempt_card ? yield(attempt_card, true) : yield(card, false)
end
ensure_purity_simple(card) { |card, attempt_save| ... } click to toggle source
# File lib/card/director/card_class.rb, line 123
def ensure_purity_simple card
  attempt_save =
    case @conflict_mode
    when :override then true
    when :default  then card.pristine?
    when :defer    then card.new?
    else
      invalid_conflict_mode!
    end
  yield card, attempt_save
end
ensuring(opts) { |ensured_card| ... } click to toggle source
# File lib/card/director/card_class.rb, line 64
def ensuring opts
  opts.symbolize_keys!
  with_conflict_mode opts.delete(:conflict) do
    card, other = fetch_for_ensure opts
    ensuring_purity(card, other, opts) do |ensured_card, attempt|
      yield ensured_card if attempt
      ensured_card
    end
  end
end
ensuring_purity(card, other, opts, &block) click to toggle source
# File lib/card/director/card_class.rb, line 110
def ensuring_purity card, other, opts, &block
  if opts[:codename] && other
    ensure_purity_advanced card, other, opts, &block
  else
    ensure_purity_simple card, &block
  end
end
fetch_and_assign(mark, opts) click to toggle source
# File lib/card/director/card_class.rb, line 102
def fetch_and_assign mark, opts
  if id(mark) && (card = fetch mark)
    card.tap { |c| c.assign_attributes opts }
  else
    new opts
  end
end
fetch_for_ensure(opts) click to toggle source
# File lib/card/director/card_class.rb, line 83
def fetch_for_ensure opts
  if opts[:codename] && opts[:name]
    fetch_for_ensure_with_codename_and_name opts
  elsif (mark = opts[:codename]&.to_sym || opts[:name])
    [fetch_and_assign(mark, opts), nil]
  else
    raise Card::Error::ServerError, "Card.ensure must have name or codename"
  end
end
fetch_for_ensure_with_codename_and_name(opts) click to toggle source
# File lib/card/director/card_class.rb, line 93
def fetch_for_ensure_with_codename_and_name opts
  codename = opts[:codename].to_sym
  codename_id = id codename
  name_id = id opts[:name]

  other_card = name_id && (codename_id != name_id) ? name_id.card : nil
  [fetch_and_assign(codename, opts), other_card]
end
invalid_conflict_mode!() click to toggle source

LOCALIZE

# File lib/card/director/card_class.rb, line 171
def invalid_conflict_mode!
  raise Card::Error::ServerError, "invalid conflict mode: #{@conflict_mode}. " \
                                  "Must be defer, default, or override"
end
with_conflict_mode(mode) { || ... } click to toggle source
# File lib/card/director/card_class.rb, line 75
def with_conflict_mode mode
  @conflict_mode = mode&.to_sym || :default
  yield
ensure
  Card::Director.clear
  @conflict_mode = nil
end