orgsync/active_interaction — pull request #174 by aaronjensen (2014-04-29 21:21:50+00:00)
Title: ActiveInteraction::Base leaks _validators

Some frameworks, like `client_side_validations` make use of `._validators`. Because of the way ActiveInteraction::Base includes `ActiveModel::Validations` (which differs from the way that `ActiveModel::Model` does it) only one `_validators` method and associated class attribute is defined so they all share it. This causes problems.

The below test fails:

```ruby
it 'does not leak _validators' do
first = Class.new(ActiveInteraction::Base) do
string :foo
validates_presence_of :foo
end

second = Class.new(ActiveInteraction::Base) do
string :bar
validates_presence_of :bar
end

expect(first._validators.keys).to eql [:foo]
expect(second._validators.keys).to eql [:bar]
end
```

I attempted to move includes to callbacks but this broke a couple tests.

In `ActiveInteraction::Base`

```ruby
def inherited(klass)
klass.send :include, ActiveModelable
klass.send :include, Runnable
klass.send :validate, :input_errors
klass.instance_variable_set(:@_interaction_filters, filters.dup)
end
```

In `ActiveModelable`

```ruby
extend ActiveSupport::Concern
included do #:nodoc:
extend ActiveModel::Naming
include ActiveModel::Validations
include ActiveModel::Conversion
end
```

Failures:

```
Failures:

1) ActiveInteraction::Base#compose with invalid composition has the correct errors
Failure/Error: expect(outcome.errors[:base])
expected collection contained: ["X is required", "Y is required"]
actual collection contained: ["X translation missing: en.activemodel.errors.models.9f3d193a8a7083ca65b726895b1dfade.attributes.x.missing", "Y translation missing: en.activemodel.errors.models.9f3d193a8a7083ca65b726895b1dfade.attributes.y.missing"]
the missing elements were: ["X is required", "Y is required"]
the extra elements were: ["X translation missing: en.activemodel.errors.models.9f3d193a8a7083ca65b726895b1dfade.attributes.x.missing", "Y translation missing: en.activemodel.errors.models.9f3d193a8a7083ca65b726895b1dfade.attributes.y.missing"]
# ./spec/active_interaction/base_spec.rb:317:in `block (4 levels) in '

2) ActiveInteraction::Base#execute raises an error
Failure/Error: expect { interaction.execute }.to raise_error NotImplementedError
expected NotImplementedError, got #> with backtrace:
# ./spec/active_interaction/base_spec.rb:325:in `block (4 levels) in '
# ./spec/active_interaction/base_spec.rb:325:in `block (3 levels) in '
# ./spec/active_interaction/base_spec.rb:325:in `block (3 levels) in '
```