Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Regression: HABTM deletion fails when join table has foreign keys

#5674

Given models One and Two, where One declares "has_and_belongs_to_many :twos", it's no longer possible to delete an instance of One if there are corresponding rows in the join table (ones_twos) and that join table has a foreign key on one_id.

In Rails < 3, the rows in the join table would be deleted before the parent object, but in 3.0 the join table rows appear to be deleted afterwards, and so any foreign key will block the deletion of the parent object -- dropping the foreign keys makes everything work, but this is an extremely undesirable workaround.

There's no obvious option for habtm to fix this behavior, and no mention of related changes in the Rails 3 Guides, so I can only guess that this is a regression.

The problem presents itself with both PostgreSQL 8.4 and 9.0, but would also presumably affect other DBs with foreign key support.

Reported by Steve Purcell · September 21st, 2010 @ 11:19 AM

State: committed
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Steve Purcell
    Steve Purcell

    The attached patch to schema.rb causes the relevant tests to fail with the problem as described.

    September 21st, 2010 @ 11:39 AM

  2. gnufied
    gnufied

    Verified. Problem exists. A quick workaround is, to have ON DELETE CASCADE on such foreign keys.

    September 21st, 2010 @ 07:10 PM

  3. Steve Purcell
    Steve Purcell

    Indeed, though it's generally recommended to avoid ON DELETE CASCADE, since records can disappear without Rails knowing. For example, adding ON DELETE CASCADE to developers_projects breaks 2 cases in NestedScopingTest.

    September 21st, 2010 @ 07:54 PM

  4. gnufied
    gnufied
    • Tag changed from 3.0, activerecord, habtm to 3.0, activerecord, habtm, patch

    Attached patch fixes the problem and updates the failing test cases to accomodate the new behavior.

    September 21st, 2010 @ 09:03 PM

  5. Aaron Patterson
    Aaron Patterson
    • State changed from new to committed
    • Importance changed from to Low

    I've committed this, thanks!

    September 21st, 2010 @ 10:02 PM

  6. Steve Purcell
    Steve Purcell

    Cool, thanks! -- will that fix get into 3.0.1? I don't see it in the 3-0-stable branch, but maybe the plan is to merge master for that release.

    September 22nd, 2010 @ 10:47 AM

  7. Aaron Patterson
    Aaron Patterson

    No! I made a mistake. I was going to merge to the 3-0-stable branch, but I forgot! Thanks for reminding me. It should be on the 3-0-stable branch now. Thanks!

    September 22nd, 2010 @ 04:37 PM

  8. Steve Purcell
    Steve Purcell

    In case it helps anyone while we wait for 3.0.1, I've posted the monkey patch initializer I'm using to work around this issue here:

    http://gist.github.com/605268

    October 4th, 2010 @ 10:43 AM

  9. Evgeniy Dolzhenko
    Evgeniy Dolzhenko

    The problem with the patch that was committed is that now before_destroy callbacks on the models with HABTM associations don't see the corresponding associations. For example if you wanted to prevent models referenced by HABTM from being destroyed you can't do that with before_destroy callback any longer.

    November 23rd, 2010 @ 12:09 PM

  10. Hemant Kumar
    Hemant Kumar

    Can you get a test case attached, I will see what I can do to fix the problem.

    November 23rd, 2010 @ 12:25 PM