hanswurst: Be a couch potato and play different roles
Hanswurst is a library that uses couch potato to create arbitrary objects that may have different roles. The roles determine the properties and they can be mixed and matched at will.
Installation
hanswurst is only tested with ruby 1.9.2 and above.
Install it as a gem:
sudo gem install hanswurst
or in rvm:
gem install hanswurst
Example:
first you have to build your roles as normal couch potato classes
class Person
include CouchPotato::Persistence
property :last_name
property :first_name
def name()
"#{firstname} #{lastname}"
end
validates_presence_of :last_name
end
class Product
include CouchPotato::Persistence
property :price
property :in_stock
end
then you may use them as you like
hw = Hanswurst.new
hw << {:person => Person} # first role then class
hw.person.first_name = 'Diederich'
hw.person.last_name = 'Hessling' # an RoleNotValid error is raised if hw.person.last_name is missing
# you may also use some syntatic sugar with 'as', the following does the same thing as above
hw = Hanswurst.new :person => Person.new(:first_name => 'Diederich', :last_name => 'Hessling')
# this is also possible
hw.product = Product.new :price => 20, :in_stock => 1
id = CouchPotato.database.save_document hw
later...
hw = CouchPotato.database.load_document id
hw.person.first_name # => 'Diederich'
hw.person.name # => 'Diederich Hessling'
hw.product.price # => 20
you may also set roles as properties of other roles
class Address
include CouchPotato::Persistence
property :street
property :zip
property :city
end
class Person
include CouchPotato::Persistence
property :address_privat
property :address_work
# gets invalid unless address_privat / address_work are instances of Address
validates :address_privat, :hanswurst => {:class => Address}
validates :address_work, :hanswurst => {:class => Address}
property :last_name
property :first_name
end
hw = Hanswurst.new :employee => Person.new(:last_name => 'Hessling')
emp = hw.employee
emp.address_privat = Address.new :city => 'Berlin'
emp.address_work = Address.new :city => 'Potsdam'
as comfort you might delegate to some roles property
class Address
include CouchPotato::Persistence
property :street
property :zip
property :city
end
class Person
include CouchPotato::Persistence
include Hanswurst::Delegates
property :address
delegates [:street,:zip,:city] => :address
end
hw = Hanswurst.new :employee => Person.new(:last_name => 'Hessling'), :address => Address.new
emp = hw.employee
emp.city = 'Berlin' # => sets emp.addess.city = 'Berlin'
emp.city # => gets emp.addess.city
you might also share dependancies
class Address
include CouchPotato::Persistence
property :street
property :zip
property :city
end
class Person
include CouchPotato::Persistence
include Hanswurst::Shares
shares :address_privat => Address
shares :address_work => Address
property :last_name
property :first_name
end
hw = Hanswurst.new :employee => Person.new(:last_name => 'Hessling')
hw.address_privat.city = 'Berlin'
hw.address_work.city = 'Potsdam'
All views are attached to the hanswurst design document You may create general views:
Hanswurst.view :all, :key => :created_at
or views specific for a role
Hanswurst.view_for :employee, :all, :key => :created_at
# execute them this way
CouchPotato.database.view Hanswurst.employee_all
the same works with lists.
You may subclass Hanswurst to do further separation and mix the native properties of Hanswursts / its subclasses with the roles properties.
Contributing to hanswurst
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright (c) 2012 Marc Rene Arns. See LICENSE.txt for further details.