lib/ohm.rb in ohm-0.1.0.rc2 vs lib/ohm.rb in ohm-0.1.0.rc4

- old
+ new

@@ -516,11 +516,11 @@ def self.to_proc Proc.new { |id| self[id] } end def self.all - @all ||= Ohm::Model::Index.new(key(:all), Wrapper.wrap(self)) + Ohm::Model::Index.new(key(:all), Wrapper.wrap(self)) end def self.attributes @@attributes[self] end @@ -621,10 +621,52 @@ # @param att [Symbol] Attribute to decrement. def decr(att, count = 1) incr(att, -count) end + # Export the id and errors of the object. The `to_hash` takes the opposite + # approach of providing all the attributes and instead favors a + # white listed approach. + # + # @example + # + # person = Person.create(:name => "John Doe") + # person.to_hash == { :id => '1' } + # # => true + # + # # if the person asserts presence of name, the errors will be included + # person = Person.create(:name => "John Doe") + # person.name = nil + # person.valid? + # # => false + # + # person.to_hash == { :id => '1', :errors => [[:name, :not_present]] } + # # => true + # + # # for cases where you want to provide white listed attributes just do: + # + # class Person < Ohm::Model + # def to_hash + # super.merge(:name => name) + # end + # end + # + # # now we have the name when doing a to_hash + # person = Person.create(:name => "John Doe") + # person.to_hash == { :id => '1', :name => "John Doe" } + # # => true + def to_hash + attrs = {} + attrs[:id] = id unless new? + attrs[:errors] = errors unless errors.empty? + attrs + end + + def to_json(*args) + to_hash.to_json(*args) + end + def attributes self.class.attributes end def counters @@ -642,11 +684,16 @@ def ==(other) other.kind_of?(self.class) && other.key == key rescue MissingID false end + alias :eql? :== + def hash + new? ? super : key.hash + end + # Lock the object before executing the block, and release it once the block is done. def mutex lock! yield self @@ -692,24 +739,44 @@ def key(*args) self.class.key(id, *args) end def write - unless attributes.empty? - attributes.each do |att| + unless (attributes + counters).empty? + atts = (attributes + counters).inject([]) { |ret, att| value = send(att).to_s - if value.empty? - db.hdel(key, att) - else - db.hset(key, att, value) - end + ret.push(att, value) if not value.empty? + ret + } + + db.multi do + db.del(key) + db.hmset(key, *atts.flatten) if atts.any? end end end + def write_remote(att, value) + write_local(att, value) + + if value.to_s.empty? + db.hdel(key, att) + else + db.hset(key, att, value) + end + end + def self.const_missing(name) - Wrapper.new(name) { const_get(name) } + wrapper = Wrapper.new(name) { const_get(name) } + + # Allow others to hook to const_missing. + begin + super(name) + rescue NameError + end + + wrapper end private # Provides access to the Redis database. This is shared accross all models and instances.