#1108 ✓resolved
Sindre Aarsaether

Related resources does not get saved

Reported by Sindre Aarsaether | October 25th, 2009 @ 01:42 PM | in 0.10.2

This might be a more complicated reduction than strictly necessary. After updating to the latest dm-core yesterday I have been experiencing strange scenarios where related resources are not saved, and this is the simplest case I have managed to come up with now. In my more complex scenarios I have provoked it in what seems as a much simpler case (without the cross-relationships), but the env. is complex, so I am not sure.

Here goes:


# encoding: utf-8
require 'rubygems'
require 'dm-core'

DataMapper::setup(:default, "mysql://root@localhost/dm_core_test") 
DataObjects::Mysql.logger = DataObjects::Logger.new(STDOUT, :debug)

class Company
  include DataMapper::Resource

  property :id, Serial
  property :name, String
  property :owner_id, Integer
  belongs_to :owner, :model => "Person"
  has n, :people
end

class Phone
  include DataMapper::Resource
  
  property :id, Serial
  property :nr, Integer
  property :person_id, Integer
  belongs_to :person
end

class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  property :company_id, Integer
  belongs_to :company
  has n, :phones
end

DataMapper.auto_migrate!

company = Company.create :name => "Kramerica"
company.owner = company.people.new(:name => "Kramer")
company.owner.phones.new :nr => 10
company.save

puts company.owner.inspect # Person has been saved, but the phone has not:
puts company.owner.phones.inspect # => [#<Phone @id=nil @nr=10 @person_id=1>] (NOT SAVED)

# UPDATED WITH SIMPLER CASE

In this example it seems to be related (yet again) to a relationship where two models are connected through belongs_to both ways (A has n, B, and A belongs_to B).

I find this actually happens in quite a lot of scenarios, where a company/user/thingie has many phone-numbers/addresses/emails etc, but ONE main. group has many users but ONE admin. I know this could be 'solved' by a m-2-m with additional info, but this is cleaner imho, and should atleast be supported.

Comments and changes to this ticket

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) October 26th, 2009 @ 05:48 AM

    • Milestone set to 0.10.2
    • State changed from “unconfirmed” to “confirmed”
    • Assigned user set to “Dan Kubb (dkubb)”

    @Sindre: Can you try edge dm-core and let me know if the fixes I just committed resolve your issue? They seem to pass with this spec, but I want to verify before closing this ticket.

  • Sindre Aarsaether

    Sindre Aarsaether October 26th, 2009 @ 08:27 AM

    The example I posted to you passes, but my more complex scenario is still failing the same way. Will need to sit down later today and try to make a new example.

  • Sindre Aarsaether

    Sindre Aarsaether October 26th, 2009 @ 08:38 AM

    Just to show before I make a new reduction. This is what happens (still):

     # invoice has states
     # invoice belongs to state
     # state has fees
    
    i = Invoice.first; s = i.state
    => #<InvoicedState @id=2 @nr=2 @type=InvoicedState @name=nil @due_on=#<Date: 2007-11-14 (4908837/2,0,2299161)> @options={"wait_days"=>0} @sent_on=#<Date: 2007-11-04 (4908817/2,0,2299161)> @entered_at=#<DateTime: 2007-11-04T00:00:00-04:00 (7363226/3,-1/6,2299161)> @exited_at=nil @invoice_id=1 @prev_id=1>
    irb(main):003:0> a = s.fees.new :sum => 10000
    => #<Fee @id=nil @since=nil @till=nil @rate=nil @sum=#<BigDecimal:1013f1970,'0.1E5',9(18)> @invoice_id=nil @invoice_state_id=2>
    irb(main):005:0> i.save
    => true
    irb(main):006:0> a
    => #< Fee @id=nil @since=nil @till=nil @rate=nil @sum=#<BigDecimal:1013f1970,'0.1E5',9(18)> @invoice_id=nil @invoice_state_id=2>
    
  • Sindre Aarsaether

    Sindre Aarsaether October 27th, 2009 @ 07:17 AM

    Much easier to show the new case than I thought:

    
    # encoding: utf-8
    require 'rubygems'
    require 'dm-core'
    
    DataMapper::setup(:default, "mysql://root@localhost/dm_core_test") 
    DataObjects::Mysql.logger = DataObjects::Logger.new(STDOUT, :debug)
    
    class Company
      include DataMapper::Resource
    
      property :id, Serial
      property :name, String
      property :owner_id, Integer
      belongs_to :owner, :model => "Person"
      has n, :people
    end
    
    class Phone
      include DataMapper::Resource
      
      property :id, Serial
      property :nr, Integer
      property :person_id, Integer
      belongs_to :person
    end
    
    class Person
      include DataMapper::Resource
      property :id, Serial
      property :name, String
      property :company_id, Integer
      belongs_to :company
      has n, :phones
    end
    
    DataMapper.auto_migrate!
    
    company = Company.create :name => "Kramerica"
    company.owner = company.people.new(:name => "Kramer")
    company.save
    
    # Load it again
    c = Company.get(1)
    c.owner.phones.new :nr => 10
    c.save
    
    puts c.owner.inspect # Person has been saved, but the phone has not:
    puts c.owner.phones.inspect # => [#<Phone @id=nil @nr=10 @person_id=1 @company_id=nil>] (NOT SAVED)
    
  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) October 27th, 2009 @ 11:56 AM

    • State changed from “confirmed” to “resolved”

    After discussion with Sindre in IRC, I am marking this ticket as closed.

    The behavior above is currently not supported since Resource#save only saves it's direct parents/grandparents/etc, itself and it's own children, but not the children of those parents.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

People watching this ticket

Pages