Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/amberbit/mongomapper into f…
Browse files Browse the repository at this point in the history
…rom-array

* 'master' of git://github.com/amberbit/mongomapper:
  initial version of inverse many-to-many association done
  • Loading branch information
bkeepers committed Sep 5, 2011
2 parents 5a70995 + 7ab0178 commit 5d3e5e4
Show file tree
Hide file tree
Showing 5 changed files with 466 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/mongo_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module Associations
autoload :OneAsProxy, 'mongo_mapper/plugins/associations/one_as_proxy'
autoload :OneEmbeddedProxy, 'mongo_mapper/plugins/associations/one_embedded_proxy'
autoload :InArrayProxy, 'mongo_mapper/plugins/associations/in_array_proxy'
autoload :InForeignArrayProxy, 'mongo_mapper/plugins/associations/in_foreign_array_proxy'
end
end

Expand Down
8 changes: 6 additions & 2 deletions lib/mongo_mapper/plugins/associations/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Base
attr_reader :name, :options, :query_options

# Options that should not be considered MongoDB query options/criteria
AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic, :autosave]
AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :in_foreign, :polymorphic, :autosave]

def initialize(name, options={}, &extension)
@name, @options, @query_options, @original_options = name.to_sym, {}, {}, options
Expand All @@ -28,13 +28,17 @@ def polymorphic?
end

def as?
!!@options[:as]
!in_foreign_array? && !!@options[:as]
end

def in_array?
!!@options[:in]
end

def in_foreign_array?
!!@options[:in_foreign]
end

def embeddable?
klass.embeddable?
end
Expand Down
135 changes: 135 additions & 0 deletions lib/mongo_mapper/plugins/associations/in_foreign_array_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# encoding: UTF-8
module MongoMapper
module Plugins
module Associations
class InForeignArrayProxy < Collection
include DynamicQuerying::ClassMethods

def find(*args)
query.find(*scoped_ids(args))
end

def find!(*args)
query.find!(*scoped_ids(args))
end

def paginate(options)
query.paginate(options)
end

def all(options={})
query(options).all
end

def first(options={})
query(options).first
end

def last(options={})
query(options).last
end

def count(options={})
query(options).count
end

def destroy_all(options={})
all(options).each do |doc|
doc.destroy
end
reset
end

def delete_all(options={})
docs = query(options).fields(:_id).all
klass.delete(docs.map { |d| d.id })
reset
end

def nullify
replace([])
reset
end

def create(attrs={})
doc = klass.create(attrs)
if doc.persisted?
inverse_association(doc) << proxy_owner
doc.save
reset
end
doc
end

def create!(attrs={})
doc = klass.create!(attrs)

if doc.persisted?
inverse_association(doc) << proxy_owner
doc.save
reset
end
doc
end

def <<(*docs)
flatten_deeper(docs).each do |doc|
inverse_association(doc) << proxy_owner
doc.save
end
reset
end
alias_method :push, :<<
alias_method :concat, :<<

def replace(docs)
doc_ids = docs.map do |doc|
doc.save unless doc.persisted?
inverse_association(doc) << proxy_owner
doc.save
doc.id
end

replace_selector = { options[:in_foreign] => proxy_owner.id }
unless doc_ids.empty?
replace_selector[:_id] = {"$not" => {"$in" => doc_ids}}
end

klass.collection.update( replace_selector,
{ "$pull" => { options[:in_foreign] => proxy_owner.id}},
{ :multi => true } )

reset
end

private
def query(options={})
klass.
query(association.query_options).
update(options).
update(criteria)
end

def criteria
{options[:in_foreign] => proxy_owner.id}
end

def scoped_ids(args)
valid = args.flatten.map do |id|
id = ObjectId.to_mongo(id) if klass.using_object_id?
id
end
valid.empty? ? nil : valid
end

def find_target
all
end

def inverse_association(doc)
doc.send(options[:as].to_s.pluralize)
end
end
end
end
end
4 changes: 3 additions & 1 deletion lib/mongo_mapper/plugins/associations/many_association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def proxy_class
ManyPolymorphicProxy
elsif as?
ManyDocumentsAsProxy
elsif in_foreign_array?
InForeignArrayProxy
elsif in_array?
InArrayProxy
else
Expand Down Expand Up @@ -64,4 +66,4 @@ def autosave?
end
end
end
end
end
Loading

0 comments on commit 5d3e5e4

Please sign in to comment.