#395 ✓resolved
Anthony Williams

ManyToOne::Proxy#replace no longer sets the foreign key immediately

Reported by Anthony Williams | June 17th, 2008 @ 12:26 PM

Recent changes to the association proxies mean that belongs_to foreign keys are no longer set when you assign the association:

Yard.new(:engine => Engine.first).engine_id
# => nil

I think this is due to recent changes to ManyToOne::Proxy#replace

As far as I can tell, the foreign key is set later, when you call Resource#save. This is a problem since validation may depend on the foreign key being set (especially if using auto-validation, and the column is :nullable => false).

I've attached a failing spec which demonstrates the problem.

Comments and changes to this ticket

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) June 17th, 2008 @ 05:16 PM

    • Assigned user changed from “Sam Smoot” to “Dan Kubb (dkubb)”
    • State changed from “new” to “open”
    • Milestone cleared.
  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) June 17th, 2008 @ 05:43 PM

    • State changed from “open” to “resolved”

    Thanks for the failing spec, it allowed me to figure out the issue alot more quickly than a stacktrace or a general description.

    This issue should be resolved by the following commit:

    http://github.com/sam/dm-core/co...

    I am closing this ticket for now. If this did not resolve your issue please add a comment and I'll reopen it.

  • Anthony Williams

    Anthony Williams June 17th, 2008 @ 07:28 PM

    Thanks for the fast response.

    Just tested this out and unfortunately I seem to have uncovered a small problem. The value in the database is being saved correctly, but using #reload on the Resource results in the foreign key attribute being set to nil (still, the database isn't affected unless you call #save again).

    I checked out the previous commit (f7d76ee9) and the problem isn't present there.

    Attached a small diff demonstrating this.

    yard = Yard.create!(:engine => Engine.first)
    yard.engine_id # => Integer
    yard.reload
    yard.engine_id # => nil
    
  • Anthony Williams

    Anthony Williams June 17th, 2008 @ 07:38 PM

    I think I've sorted it: Resource#reload calls #reload on each of the associations, and ManyToOne#reload in turn runs replace(nil), which unsets the foreign key.

    I've attached a third patch which reverts ManyToOne#reload to how it was before. This passes fine for me.

  • Anthony Williams

    Anthony Williams June 17th, 2008 @ 07:42 PM

    Heh... attached a fourth patch (0004) which removes my comments, and adds a unit test to ensure that @parent is set to nil.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) June 18th, 2008 @ 01:30 AM

    • State changed from “resolved” to “open”

    Anthony, I just committed the following fix and some integration specs:

    http://github.com/sam/dm-core/co...

    Can you verify if this fixed the issue for you?

  • Anthony Williams

    Anthony Williams June 18th, 2008 @ 12:36 PM

    Hi Dan,

    That seems to have fixed it.

    However, I've been fiddling about with one or two association issues today and realised that the spec I submitted yesterday is complete rubbish. Since Proxy doesn't define instance_variable_get, @association.instance_variable_get(:@parent) ends up running on the @parent (via Proxy#method_missing), rather than the proxy itself.

    I've fixed this in my own fork at: http://github.com/anthonyw/dm-co...

    Also followed that up with a correction to my spelling error: http://github.com/anthonyw/dm-co...

    I'm still getting up to speed with forks on Github, but hopefully you should be able to pull in those changes if you're happy with them.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) June 23rd, 2008 @ 07:02 PM

    • State changed from “open” to “resolved”

    Anthony, I've merged your fork into the master repo and all specs passwed, so I'm closing this ticket.

    Sam, could you set up Anthony (github: anthonyw) with commit rights to the master repos?

  • Sam Smoot
  • Michael Aufreiter

    Michael Aufreiter July 4th, 2008 @ 04:56 AM

    • Tag set to associations, dm-core

    There's still something unclear for me.

    m = Machine.new(:serial_number => "BLA123", :machinemodel => Machinemodel.new(:name => "XA2312"))
    m.save
    m.machinemodel_id # => nil
    

    I found out that when using Machinemodel.create instead of .new it works properly.

    m = Machine.new(:serial_number => "BLA123", :machinemodel => Machinemodel.create(:name => "XA2312"))
    m.save
    m.machinemodel_id # => 1
    

    So my question is: What exactly is the difference between .new and .create regarding associations?

    Thanks a lot,

    Michael

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

Referenced by

Pages