Permalink
Browse files

Add Attribute and AttributeSet classes

  • Loading branch information...
1 parent 6ca6cde commit 36d7047ee1b27fcc5730a91d1d2c54d1e071ad39 @jgaskins committed Feb 26, 2012
Showing with 140 additions and 75 deletions.
  1. +9 −0 lib/attribute.rb
  2. +21 −0 lib/attribute_set.rb
  3. +79 −74 lib/perpetuity/mapper.rb
  4. +17 −0 spec/attribute_set_spec.rb
  5. +13 −0 spec/attribute_spec.rb
  6. +1 −1 spec/mapper_spec.rb
View
@@ -0,0 +1,9 @@
+module Perpetuity
+ class Attribute
+ attr_reader :name, :type
+ def initialize(name, type)
+ @name = name
+ @type = type
+ end
+ end
+end
View
@@ -0,0 +1,21 @@
+module Perpetuity
+ class AttributeSet
+ include Enumerable
+
+ def initialize
+ @attributes = []
+ end
+
+ def << attribute
+ @attributes << attribute
+ end
+
+ def each &block
+ @attributes.each(&block)
+ end
+
+ def [] name
+ @attributes.find { |attr| attr.name == name }
+ end
+ end
+end
View
@@ -1,92 +1,97 @@
-class Perpetuity::Mapper
- def self.attribute name, type
- @attributes ||= []
- @attributes << name.to_sym
- end
-
- def self.attributes
- @attributes
- end
-
- def self.delete_all
- data_source.delete_all mapped_class
- end
-
- def self.serializable_types
- @serializable_types ||= [NilClass, TrueClass, FalseClass, Fixnum, Bignum, Float, String, Array, Hash]
- end
-
- def self.insert object
- raise "#{object} is invalid and cannot be persisted." if object.respond_to?(:valid?) and !object.valid?
- serializable_attributes = {}
- attributes_for(object).each_pair do |attribute, value|
- if serializable_types.include? value.class
- serializable_attributes[attribute] = value
- elsif value.respond_to?(:id)
- serializable_attributes[attribute] = { class_name: value.class.to_s, id: value.id }
- else
- raise "Must persist #{attribute} (#{value.inspect}) before persisting this #{object.inspect}."
- end
+require 'attribute_set'
+require 'attribute'
+
+module Perpetuity
+ class Mapper
+ def self.attribute name, type
+ @attributes ||= AttributeSet.new
+ @attributes << Attribute.new(name, type)
end
- new_id = data_source.insert mapped_class, serializable_attributes
- give_id_to object, new_id
- end
+ def self.attributes
+ @attributes.map(&:name)
+ end
- def self.give_id_to object, given_id
- object.define_singleton_method :id, -> { given_id }
- end
+ def self.delete_all
+ data_source.delete_all mapped_class
+ end
- def self.attributes_for object
- attrs = {}
- attributes.each do |attrib|
- attrs[attrib] = object.send(attrib)
+ def self.serializable_types
+ @serializable_types ||= [NilClass, TrueClass, FalseClass, Fixnum, Bignum, Float, String, Array, Hash]
end
- attrs
- end
- def self.data_source
- Perpetuity.configuration.data_source
- end
+ def self.insert object
+ raise "#{object} is invalid and cannot be persisted." if object.respond_to?(:valid?) and !object.valid?
+ serializable_attributes = {}
+ attributes_for(object).each_pair do |attribute, value|
+ if serializable_types.include? value.class
+ serializable_attributes[attribute] = value
+ elsif value.respond_to?(:id)
+ serializable_attributes[attribute] = value.id
+ else
+ raise "Must persist #{attribute} (#{value.inspect}) before persisting this #{object.inspect}."
+ end
+ end
- def self.count
- data_source.count mapped_class
- end
+ new_id = data_source.insert mapped_class, serializable_attributes
+ give_id_to object, new_id
+ end
- def self.mapped_class
- Module.const_get self.name.gsub('Mapper', '').to_sym
- end
+ def self.give_id_to object, given_id
+ object.define_singleton_method :id, -> { given_id }
+ end
- def self.first
- retrieve.limit(1).first
- end
+ def self.attributes_for object
+ attrs = {}
+ @attributes.each do |attrib|
+ attrs[attrib.name] = object.send(attrib.name)
+ end
+ attrs
+ end
- def self.all
- objects = data_source.all mapped_class
- objects.each do |object|
- object.define_singleton_method(:id) { @_id }
+ def self.data_source
+ Perpetuity.configuration.data_source
end
- end
- def self.retrieve criteria={}
- Perpetuity::Retrieval.new mapped_class, criteria
- end
+ def self.count
+ data_source.count mapped_class
+ end
- def self.find id
- retrieve(id: id).first
- end
+ def self.mapped_class
+ Module.const_get self.name.gsub('Mapper', '').to_sym
+ end
- def self.delete object
- data_source.delete object
- end
+ def self.first
+ retrieve.limit(1).first
+ end
- def self.load_association! object, attribute
- class_name = object.send(attribute)["class_name"]
- id = object.send(attribute)["id"]
+ def self.all
+ objects = data_source.all mapped_class
+ objects.each do |object|
+ object.define_singleton_method(:id) { @_id }
+ end
+ end
+
+ def self.retrieve criteria={}
+ Perpetuity::Retrieval.new mapped_class, criteria
+ end
+
+ def self.find id
+ retrieve(id: id).first
+ end
- mapper = Module.const_get("#{class_name}Mapper")
- associated_object = mapper.find(id)
- object.send("#{attribute}=", associated_object)
- end
+ def self.delete object
+ data_source.delete object
+ end
+
+ def self.load_association! object, attribute
+ class_name = @attributes[attribute].type
+ id = object.send(attribute)
+
+ mapper = Module.const_get("#{class_name}Mapper")
+ associated_object = mapper.find(id)
+ object.send("#{attribute}=", associated_object)
+ end
+ end
end
View
@@ -0,0 +1,17 @@
+require 'perpetuity'
+require 'test_classes'
+
+describe Perpetuity::AttributeSet do
+ it 'contains attributes' do
+ subject << Perpetuity::Attribute.new(:article, Article)
+ subject.first.name.should == :article
+ subject.first.type.should == Article
+ end
+
+ it 'can access attributes by name' do
+ subject << Perpetuity::Attribute.new(:article, Article)
+ subject << Perpetuity::Attribute.new(:user, User)
+
+ subject[:user].type.should == User
+ end
+end
View
@@ -0,0 +1,13 @@
+require 'perpetuity'
+require 'test_classes'
+
+describe Perpetuity::Attribute do
+ subject { Perpetuity::Attribute.new :article, Article }
+ it 'has a name' do
+ subject.name.should == :article
+ end
+
+ it 'has a type' do
+ subject.type.should == Article
+ end
+end
View
@@ -135,7 +135,7 @@ class TopicMapper < Perpetuity::Mapper
it 'can reference other objects' do
UserMapper.insert user
TopicMapper.insert topic
- TopicMapper.first.creator.should == { 'class_name' => 'User', 'id' => user.id }
+ TopicMapper.first.creator.should == user.id
end
it 'can retrieve associated objects' do

0 comments on commit 36d7047

Please sign in to comment.