cordawyn / spira

Fork of Spira with experimental branches, occasionally merged upstream.
http://blog.datagraph.org/2010/05/spira
The Unlicense
8 stars 2 forks source link

Infinite Loop when A linked to B and B linked to A via has_many #10

Closed abrisse closed 11 years ago

abrisse commented 11 years ago

Hi!

When 2 resources reference themselves with a has_many property, the following error is raised :

.bundle/ruby/1.9.1/gems/promise-0.3.0/lib/promise.rb:55: stack level too deep (SystemStackError)

Here is the code to reproduce it

require 'spira'

ONTOLOGY = RDF::Vocabulary.new('http://www.domain.com/ontology/ONTOLOGY/1.0#')

class Person < Spira::Base
  type ONTOLOGY.Segment
  has_many :hasTeam, :predicate => ONTOLOGY.hasTeam, :type => :Team
end

class Team < Spira::Base
  type ONTOLOGY.Team
  has_many :hasMember, :predicate => ONTOLOGY.hasMember, :type => :Person
end

Spira.add_repository! :default, RDF::Repository

person = Person.for('http://www.domain.com/resource/person')
team = Team.for('http://www.domain.com/team')

person.hasTeam = [team]
team.hasMember = [person]

person.save!
team.save!

person.reload # raises an error
abrisse commented 11 years ago

In base.rb you have on line 82 you have the promise statement :

def unserialize(value, options = {})
  if value.respond_to?(:blank?) && value.blank?
    nil
  else
    # Spira resources are instantiated as "promised"
    # to avoid instantiation loops in case of resource-to-resource relations.
    promise { instantiate_record(value) }
  end
end
cordawyn commented 11 years ago

I've added a failing spec for this bug, will take care of it as time permits. Thanks!

cordawyn commented 11 years ago

Fixed. This breaks backward compatibility a tiny bit: "has-many" relations now deal with Arrays, not Sets.

abrisse commented 11 years ago

That was quick. Thanks a lot Slava!