= CurlyMustache ActiveModel implementation for various data stores. In other words, it provides an ActiveRecord like library for data stores other than relational databases. Out of the box, it works with Memcached, Redis, Tokyo Tyrant, Cassandra and Amazon SDB. http://github.com/cjbottaro/curly_mustache == Installation sudo gem install curly_mustache CurlyMustache depends on activemodel-3.0.0beta1 and activesupport-3.0.0beta1 which are unfortunately in a state of great flux and are thus very buggy. I'm hosting patched versions that are known to work with CurlyMustache here: {activesupport-3.0.0beta1}[http://dl.dropbox.com/u/167916/stochasticbytes/activesupport-3.0.0.beta1.gem] {activemodel-3.0.0beta1}[http://dl.dropbox.com/u/167916/stochasticbytes/activemodel-3.0.0.beta1.gem] == Features * Basic ActiveRecord-like CRUD operations (new, create, destroy, find, save). * Validations (via ActiveModel). * Callbacks (via ActiveModel). * Attribute change tracking (via ActiveModel::Dirty). * Easy creation of new types. * Easy creation of new adapters (to connect to different data stores). * 100% rcov(erage)! == Quickstart If your data store speaks Memcached, then you just need to use the :memcached adapter. CurlyMustache::Base.establish_connection :adapter => :memcached, :servers => %w[one.example.com:11211 two.example.com:11211] class User < CurlyMustache::Base attribute :name, :string attribute :login_count, :integer attribute :birthday, :time validates_presence_of :name after_validation :capitalize_name def capitalize_name self.name = name.capitalize end end user = User.new :name => "chris" user.new_record? # => true user.id # => nil user.name # => "chris" user.birthday # => nil user.birthday = "03/11/1980" user.birthday_changed? # => true user.birthday.class # => Time user.birthday # => "Tue Mar 11 00:00:00 -0600 1980" user.save! user.id # => "676cef021584904876af7c4b3e42afb5" user = User.find(user.id) user.name # => "Chris" user.destroy User.find(user.id) # => CurlyMustache::RecordNotFound end The +memcache+ adapter uses memcache-client[http://github.com/mperham/memcache-client]. Whatever other options you pass to +establish_connection+ will be passed to the constructor for it. == Types Five types are defined for you: string, integer, float, time, boolean. It is easy to define new types or modify existing ones. See {Read more}[link:/classes/CurlyMustache/Attributes/Types.html] == Callbacks The following callbacks are available: before_validation_on_create after_validation_on_create before_validation_on_update after_validation_on_update before_validation after_validation before_create after_create before_update after_update before_save after_save before_destroy after_destroy after_find == Adapters You can use the {Memcached adapter}[link:/classes/CurlyMustache/Adapters/Memcached.html] with any data stores that speak memcached. There is also the {Cassandra adapter}[link:/classes/CurlyMustache/Adapters/Cassandra.html] and soon to be SDB adapter and Tokyo Tyrant table type adapter. You can create your own adapters by subclassing CurlyMustache::Adapters::Abstract and implementing a few methods. == Serializing If you need to serialize your model's attributes before sending them to the adapter, it's done by overriding {send_attributes}[link:/classes/CurlyMustache/Connection/InstanceMethods.html#M000078]. For deserialization, override {recv_attributes}[/classes/CurlyMustache/Connection/InstanceMethods.html#M000079]. This is how data flows in and out of the data store... --------------------- -------------------------- --------------- -------------- | record.attributes | ==> | record.send_attributes | ==> | adapter.put | ==> | data store | --------------------- -------------------------- --------------- -------------- --------------------- -------------------------- --------------- -------------- | record.attributes | <== | record.recv_attributes | <== | adapter.get | <== | data store | --------------------- -------------------------- --------------- -------------- == Author Christopher J. Bottaro - {cjbottaro}[http://github.com/cjbottaro]