orgsync/active_interaction — pull request #182 by tfausak (2014-05-02 22:49:57+00:00)
Title: Add interface filter

(This is like #181 but into `v1.3.0` instead of `master`.) Fixes #178.

This allows you to define an interface that an input must conform to. In most cases, you don't actually want to do this. Instead you should use a model filter. For instance, if you wanted your input to respond to `#each`, you could do this:

``` rb
class EachInteraction < ActiveInteraction::Base
interface :thing,
methods: [:each]
end
```

But what you probably want is an object that implements Enumerable. So you should do this:

``` rb
class EnumerableInteraction < ActiveInteraction::Base
model :thing,
class: Enumerable
end
```

Why have an interface filter, then? It may be that the classes you're willing to accept don't have anything in common and there's nothing you can do about it. For instance, you could have a serializer input that can take either `JSON` or `YAML`. You couldn't do that with a model filter. (Well, not without `class: Object`.) With an interface filter, you could do it.

``` rb
class SerializerInteraction < ActiveInteraction::Base
interface :serializer,
methods: [:dump, :load]
def execute
h = serializer.load('{}')
h['now'] = Time.now
serializer.dump(h)
end
end

require 'json'
SerializerInteraction.run!(serializer: JSON)
# => "{\"now\":\"2014-05-02 21:57:41 +0000\"}"

require 'yaml'
SerializerInteraction.run!(serializer: YAML)
# => "---\nnow: 2014-05-02 21:57:52.900349283 +00:00\n"
```