Saturday, June 11, 2011

MongoMapper with rspec/shoulda hack

As far as I know, MongoMapper is currently not able to handle association tests for rspec/shoulda, such as most common belongs_to, has_many, has_one. I think they are working on it, but it's not there yet.

I wrote a hack to work with MongoMapper, so far it's able to handle my simple belongs_to association, and my rspec test passes all right when it has the association and fails otherwise. As I progress through more associations, I will keep posting if it needs improvements.

In the config/initializers folder create a file mongo_mapper_ext.rb and place the following code into it:

module MongoMapperExt
module Plugins
module Associations
module ClassMethods
def reflect_on_association(association)
associations[association].extend AssociationMethods if associations[association]
end
end
module AssociationMethods
def macro
@macro = derive_macro
end
def primary_key_name
@primary_key_name ||= options[:foreign_key] || derive_primary_key_name
end
def belongs_to?
@macro == :belongs_to
end

private
def derive_primary_key_name
if belongs_to?
"#{name}_id"
elsif options[:as]
"#{options[:as]}_id"
else
klass.foreign_key
end
end

def derive_macro
case self.class.name
when "MongoMapper::Plugins::Associations::BelongsToAssociation"
:belongs_to
when "MongoMapper::Plugins::Associations::ManyAssociation"
:has_many
when "MongoMapper::Plugins::Associations::OneAssociation"
:has_one
else
"unknown association"
end
end
end
end
end
end

MongoMapper::Document.send(:include, MongoMapperExt::Plugins::Associations)


Basically, it adds some methods from the ActiveRecord reflections which are missing in MongoMapper. Why not, if MongoMapper classes already contain suitable options to work with.

No comments:

Post a Comment