forked from mongomapper/mongomapper
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ActiveRecord compatible association reflection
- Loading branch information
Showing
6 changed files
with
203 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# encoding: UTF-8 | ||
require 'mongo_mapper/plugins/reflect_on_association/active_record_association_adapter' | ||
|
||
module MongoMapper | ||
module Plugins | ||
# Provides a reflect_on_association method that returns an ActiveRecordAssociationAdapter for an association. | ||
# This adapter has an API that is a subset of ActiveRecord::Reflection::AssociationReflection. This allows | ||
# MongoMapper to be used with the association helpers in gems like simple_form and formtastic. | ||
module ReflectOnAssociation | ||
extend ActiveSupport::Concern | ||
|
||
module ClassMethods | ||
def reflect_on_association(name) | ||
ActiveRecordAssociationAdapter.for_association(associations[name]) if associations[name] | ||
end | ||
end | ||
end | ||
end | ||
end |
33 changes: 33 additions & 0 deletions
33
lib/mongo_mapper/plugins/reflect_on_association/active_record_association_adapter.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# encoding: UTF-8 | ||
module MongoMapper | ||
module Plugins | ||
module ReflectOnAssociation | ||
class ActiveRecordAssociationAdapter | ||
attr_reader :klass, :macro, :name, :options | ||
|
||
def self.for_association(association) | ||
macro = case association | ||
when MongoMapper::Plugins::Associations::BelongsToAssociation | ||
:belongs_to | ||
when MongoMapper::Plugins::Associations::ManyAssociation | ||
:has_many | ||
when MongoMapper::Plugins::Associations::OneAssociation | ||
:has_one | ||
else | ||
raise "no #{name} for association of type #{association.class}" | ||
end | ||
|
||
new(association, macro) | ||
end | ||
|
||
def initialize(association, macro) | ||
@klass, @name = association.klass, association.name | ||
# only include compatible options | ||
@options = association.options.slice(:conditions, :order) | ||
|
||
@macro = macro | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
require 'test_helper' | ||
|
||
module ReflectOnAssociationTestModels | ||
class Tree | ||
include MongoMapper::Document | ||
many :birds, :class_name => "ReflectOnAssociationTestModels::Bird" | ||
end | ||
|
||
class Bird | ||
include MongoMapper::Document | ||
belongs_to :tree, :class_name => "ReflectOnAssociationTestModels::Tree" | ||
end | ||
|
||
class Book | ||
include MongoMapper::Document | ||
many :authors, :class_name => "ReflectOnAssociationTestModels::Author", :in => :author_ids | ||
end | ||
|
||
class Author | ||
include MongoMapper::Document | ||
end | ||
|
||
class Employee | ||
include MongoMapper::Document | ||
one :desk, :class_name => "ReflectOnAssociationTestModels::Desk" | ||
end | ||
|
||
class Desk | ||
include MongoMapper::Document | ||
belongs_to :employee, :class_name => "ReflectOnAssociationTestModels::Employee" | ||
end | ||
|
||
class Order | ||
include MongoMapper::Document | ||
many :line_items, :class_name => "ReflectOnAssociationTestModels::LineItem" | ||
end | ||
|
||
class LineItem | ||
include MongoMapper::EmbeddedDocument | ||
end | ||
|
||
class Body | ||
include MongoMapper::Document | ||
one :heart, :class_name => "ReflectOnAssociationTestModels::Heart" | ||
end | ||
|
||
class Heart | ||
include MongoMapper::EmbeddedDocument | ||
end | ||
end | ||
|
||
class ReflectOnAssociationTest < Test::Unit::TestCase | ||
context "one-to-many association" do | ||
should "return :has_many association for Tree#birds" do | ||
association = ReflectOnAssociationTestModels::Tree.reflect_on_association(:birds) | ||
association.klass.should == ReflectOnAssociationTestModels::Bird | ||
association.macro.should == :has_many | ||
association.name.should == :birds | ||
association.options.should == {} | ||
end | ||
|
||
should "return :belongs_to association for Bird#tree" do | ||
association = ReflectOnAssociationTestModels::Bird.reflect_on_association(:tree) | ||
association.klass.should == ReflectOnAssociationTestModels::Tree | ||
association.macro.should == :belongs_to | ||
association.name.should == :tree | ||
association.options.should == {} | ||
end | ||
end | ||
|
||
context "many-to-many association" do | ||
should "return :has_many association for Book#authors" do | ||
association = ReflectOnAssociationTestModels::Book.reflect_on_association(:authors) | ||
association.klass.should == ReflectOnAssociationTestModels::Author | ||
association.macro.should == :has_many | ||
association.name.should == :authors | ||
association.options.should == {} | ||
end | ||
end | ||
|
||
context "one-to-one association" do | ||
should "return :has_one association for Employee#desk" do | ||
association = ReflectOnAssociationTestModels::Employee.reflect_on_association(:desk) | ||
association.klass.should == ReflectOnAssociationTestModels::Desk | ||
association.macro.should == :has_one | ||
association.name.should == :desk | ||
association.options.should == {} | ||
end | ||
|
||
should "return :belongs_to association for Desk#employee" do | ||
association = ReflectOnAssociationTestModels::Desk.reflect_on_association(:employee) | ||
association.klass.should == ReflectOnAssociationTestModels::Employee | ||
association.macro.should == :belongs_to | ||
association.name.should == :employee | ||
association.options.should == {} | ||
end | ||
end | ||
|
||
context "embeds one" do | ||
should "return :has_one association for Body#heart" do | ||
association = ReflectOnAssociationTestModels::Body.reflect_on_association(:heart) | ||
association.klass.should == ReflectOnAssociationTestModels::Heart | ||
association.macro.should == :has_one | ||
association.name.should == :heart | ||
association.options.should == {} | ||
end | ||
end | ||
|
||
context "embeds many" do | ||
should "return :has_many association for Order#line_items" do | ||
association = ReflectOnAssociationTestModels::Order.reflect_on_association(:line_items) | ||
association.klass.should == ReflectOnAssociationTestModels::LineItem | ||
association.macro.should == :has_many | ||
association.name.should == :line_items | ||
association.options.should == {} | ||
end | ||
end | ||
end |