agoragames/amico — pull request #5 by johnmetta (2012-03-07 18:53:16+00:00)
Title: Create "acts_as_amico" interface

This pull request adds "acts_as" like syntax to the amico system by creating an AmicoUser module that is injectable into ActiveRecord.

```ruby
class User < ActiveRecord::Base
acts_as_amico
end

usera = User.create
userb = user.create

usera.follow! userb
=> nil

usera.following? userb
=> true

userb.following? usera
=> false

userb.follow! usera
=> [1, 1]

puts userb.id
=> 11

usera.following
=> ["11"]
```

This interface is fully feature complete with the original Amico module, and can be used with non-id keys as well:

```ruby
class Admin < ActiveRecord::Base
acts_as_amico :amico_key => "name"
validates_uniqueness_of :name # -> do this or be sorry :)
end

usera = User.create

puts usera.id
=> 18

admin = Admin.create :name => "frank"

usera.follow! admin
=> nil

admin.follow! usera
=> [1, 1]

admin.followers
=> ["18"]

usera.followers
=> ["frank"]
```

The interface is designed by metaprogramming the [method_missing builtin](https://github.com/mettadore/amico/blob/master/lib/amico/amico_user.rb#L27) and catching calls to methods that the Amico module can serve.

Full RSpec tests have been written in [amico_user_spec.rb](https://github.com/mettadore/amico/blob/master/spec/amico/amico_user_spec.rb) covering feature completeness with the Amico module, as well as redundant coverage for non-id keys.

Documentation has been updated to support default usage of the library through the "acts_as" interface. Full API example documentation from the original version has been moved to API.md

# Discussion
Obviously, some discussion may be desired about specific implementation details. Furthermore, some discussion might be appropriate as to whether an "acts_as_amico" library should be built separately, on top of Amico. My thought on the latter is that the acts_as ability does not add any significant overhead, and a user need not use it if they do not want. However, since acts_as_amico has a dependency on Rails, this may not be desired. In that case, I will be happy to strip it out as a separate "acts_as_amico" library and host it myself.