Skip to content

v2.0.0

Compare
Choose a tag to compare
@tfausak tfausak released this 06 May 17:00
· 575 commits to main since this release

Changed

  • #250: Replaced symbolic errors with Rails 5-style detailed errors.
  • #269: Prevented proc defaults from being eagerly evaluated.
  • #264: Renamed model filter to object.
  • #213: Remove transaction support. Database transactions will need to be
    handled manually now.
  • #214: Results are returned from invalid outcomes.
  • #164: Changed the hash filter to use hashes with indifferent access.
  • #236: Changed the file filter to accept anything that responds to eof?.

Security

  • #215: Rather than symbolizing keys all hashes now use indifferent access.
    This takes care of potential but unlikely DoS attacks noted in #163.

Upgrading

Please read through the Changed section for a full list of changes.

The contents of the execute method are no longer wrapped in a transaction. You
can manually add a transaction if you need it by using
ActiveRecord::Base.transaction. We've also removed the transaction method since
it no longer has a use.

# v1.6
class Example < ActiveInteraction::Base
  # This is the default.
  transaction true

  def execute
    # ...
  end
end

# v2.0
class Example < ActiveInteraction::Base
  def execute
    ActiveRecord::Base.transaction do
      # ...
    end
  end
end

Symbolic errors should now be added with add instead of add_sym. Additionally,
you can view the errors with details instead of symbolic. This aligns with the
direction Rails is taking.

# v1.6
class Example < ActiveInteraction::Base
  def execute
    errors.add_sym :base, :invalid
    errors.add_sym :base, :custom, '...'
  end
end
Example.run.errors.symbolic
# => {:base=>[:invalid,:custom]}

# v2.0
class Example < ActiveInteraction::Base
  def execute
    errors.add :base, :invalid
    errors.add :base, :custom, message: '...'
  end
end
Example.run.errors.details
# => {:base=>[{:error=>:invalid},{:error=>:custom,:message=>'...'}]}

In the hash filter we've stopped converting all inputs to symbols and instead we
now convert the hash to a hash with indifferent access. This means hash keys will
display as strings instead of symbols.

class Example < ActiveInteraction::Base
  hash :options,
    strip: false

  def execute
    options.keys
  end
end

# v1.6
Example.run!(options: { enable: true })
# => [:enable]

# v2.0
Example.run!(options: { enable: true })
# => ["enable"]

We added the ability to return results from invalid interactions. Setting the result to
nil was unnecessary. The right way to check for validity is to use valid?. This change
allows you to return something from an interaction even if there are errors. This can be
very useful when updating an existing record.

class Example < ActiveInteraction::Base
  def execute
    errors.add(:base)
    'something'
  end
end

# v1.6
outcome = Example.run
outcome.valid?
# => false
outcome.result
# => nil

# v2.0
outcome = Example.run
outcome.valid?
# => false
outcome.result
# => "something"

When setting a default with a Proc is is no longer eagerly evaluated.

class Example < ActiveInteraction::Base
  boolean :flag,
    default: -> {
      puts 'defaulting...'
      true
    }

  def execute
    puts 'executing...'
  end
end

# v1.6
# defaulting...
Example.run
# executing...

# v2.0
Example.run
# defaulting...
# executing...