Skip to content

Instantly share code, notes, and snippets.

@talos
Created March 11, 2011 03:13
Show Gist options
  • Save talos/865393 to your computer and use it in GitHub Desktop.
Save talos/865393 to your computer and use it in GitHub Desktop.
Bypass the DataMapper's infinite loop bug, described at http://datamapper.lighthouseapp.com/projects/20609/tickets/1431-stack-level-too-deep-when-collecting-relations , by converting a collection to an array before iterating over its members' associations
require 'rubygems'
dm_version = "=1.0.2"
gem "dm-core", dm_version
require 'dm-core'
gem "dm-migrations", dm_version
require 'dm-migrations'
gem "dm-serializer", dm_version
require 'dm-serializer'
require 'spec'
require 'spec/autorun'
require 'spec/interop/test'
class Thing
include DataMapper::Resource
property :id, Serial, :key => true
has n, :thing_taggings
has n, :tags, :through => :thing_taggings
end
class ThingTagging
include DataMapper::Resource
property :id, Serial, :key => true
belongs_to :thing
belongs_to :tag
end
class Tag
include DataMapper::Resource
property :id, Serial, :key => true
property :title, String, :length => 128
has n, :thing_taggings
has n, :things, :through => :thing_taggings
end
DataMapper.finalize
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/test.sqlite3")
describe "Problem" do
before do
DataMapper.auto_migrate!
one = Tag.create(:title => "one")
two = Tag.create(:title => "two")
three = Tag.create(:title => "three")
four = Tag.create(:title => "four")
one_two = Thing.create
one_two.thing_taggings.create(:tag => one)
one_two.thing_taggings.create(:tag => two)
three_two = Thing.create
three_two.thing_taggings.create(:tag => three)
three_two.thing_taggings.create(:tag => two)
three_four = Thing.create
three_four.thing_taggings.create(:tag => three)
three_four.thing_taggings.create(:tag => four)
@things = ["three", "four"].map{|tag| Tag.all(:title => tag).things }.reduce{|x, y| x & y }
end
it "should collect things" do
r = {:status => "success", :things => @things}
r[:things].should have(1).item
end
# it "should collect things with relations" do
# r = {:status => "success", :things => @things.map{|e| {:tags => e.tags}}}
# r[:things].should have(1).item
# r[:things].first[:tags].should have(2).items
# end
it "will collect things with relations if the collection is converted to an array before" do
r = {:status => "success", :things => @things.to_a.map{|e| {:tags => e.tags}}}
r[:things].should have(1).item
r[:things].first[:tags].should have(2).items
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment