From e79c0a0587c2f47a8dcec709eaf9d03a8e7381d4 Mon Sep 17 00:00:00 2001 From: Yurii Rashkovskii Date: Tue, 29 Apr 2008 09:38:08 +0300 Subject: [PATCH] Initial has_many on views implementation. Still has some more or less serious flaws (it is still WIP), but appears to work if respective view is updated manually. Specs are not updated (need to update views explicitely to let specs run) --- lib/strokedb/document/associations.rb | 52 +++++++++++++++++---------- lib/strokedb/views/view.rb | 2 +- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/strokedb/document/associations.rb b/lib/strokedb/document/associations.rb index 22d87883..c482aec0 100644 --- a/lib/strokedb/document/associations.rb +++ b/lib/strokedb/document/associations.rb @@ -1,6 +1,30 @@ module StrokeDB module Associations + + AssociationViewImplementation = Proc.new do |view| + def view.map(uuid, doc) + reference_slotname = self[:reference_slotname] + through = self[:through] + expected_meta = self[:expected_meta] + + begin + through.each {|t| doc = doc.send(t) } + rescue SlotNotFoundError + doc = nil + end + + if doc.meta.name == expected_meta && + reference_slotname_value = doc[reference_slotname] + [ + [ + reference_slotname_value, + doc + ] + ] + end + end + end module HasManyAssociation attr_reader :association_owner, :association_slotname @@ -28,7 +52,7 @@ def association_reference_slotname end def association_meta - association_owner.meta["has_many_#{association_slotname}"][:meta] + association_owner.meta["has_many_#{association_slotname}"][:expected_meta] end end @@ -40,7 +64,6 @@ def has_many(slotname, opts={}, &block) through = opts['through'] || [] through = [through] unless through.is_a?(Array) meta = (through.shift || slotname).to_s.singularize.camelize - query = opts['conditions'] || {} extend_with = opts['extend'] || block @@ -64,7 +87,12 @@ def has_many(slotname, opts={}, &block) _t << meta meta = _t.join('::') end - @args.last.reverse_merge!({"has_many_#{slotname}" => { :reference_slotname => reference_slotname, :through => through, :meta => meta, :query => query, :extend_with => extend_with } }) + + + view = View.define!({ :reference_slotname => reference_slotname, :through => through, :expected_meta => meta, :extend_with => extend_with }.to_json, + { :reference_slotname => reference_slotname, :through => through, :expected_meta => meta, :extend_with => extend_with }, &AssociationViewImplementation) + + @args.last.reverse_merge!({"has_many_#{slotname}" => view}) define_method(slotname) do _has_many_association(slotname,{}) end @@ -78,22 +106,8 @@ def has_many(slotname, opts={}, &block) def initialize_associations define_method(:_has_many_association) do |slotname, additional_query| slot_has_many = meta["has_many_#{slotname}"] - reference_slotname = slot_has_many[:reference_slotname] - through = slot_has_many[:through] - meta = slot_has_many[:meta] - query = slot_has_many[:query] - effective_query = query.merge(:meta => meta.constantize.document, reference_slotname => self).merge(additional_query) - - result = LazyArray.new.load_with do |lazy_array| - store.search(effective_query).map do |d| - begin - through.each { |t| d = d.send(t) } - rescue SlotNotFoundError - d = nil - end - d - end.compact - end + StrokeDB::Associations::AssociationViewImplementation.call(slot_has_many) + result = slot_has_many.find(:key => self) if extend_with = slot_has_many[:extend_with] result.extend(extend_with.constantize) end diff --git a/lib/strokedb/views/view.rb b/lib/strokedb/views/view.rb index f549634c..4dc353b9 100644 --- a/lib/strokedb/views/view.rb +++ b/lib/strokedb/views/view.rb @@ -22,7 +22,7 @@ module StrokeDB # When :heads is used, previous versions are removed from the index. "strategy" => "heads", # heads|versions } - + on_new_document do |viewdoc| viewdoc.reverse_update_slots(DEFAULT_VIEW_OPTIONS) end