Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected behaviour of non-persisted has_many through associations #9548

Closed
RKushnir opened this issue Mar 4, 2013 · 6 comments
Closed

Comments

@RKushnir
Copy link
Contributor

RKushnir commented Mar 4, 2013

Consider a basic hm:t association

class Host < ActiveRecord::Base
  has_many :links
  has_many :pages, through: :links
end

(Link and Page are trivial).

If you add and remove an item from links, it still thinks the item is magically present... in the empty collection:

host = Host.new
page = Page.new
host.pages.include? page
 => false
host.pages << page
host.pages.delete page
host.pages.include? page
 => true 
host.pages
 => #<ActiveRecord::Associations::CollectionProxy []>

Tried this on both 3.2.12 and 4.0.0.beta1.

PS. If you save the records, it works as expected.

@senny
Copy link
Member

senny commented Mar 5, 2013

this looks strange indeed. I'll take a look and report back.

@senny
Copy link
Member

senny commented Mar 5, 2013

I can confirm the problem. It's related to the join model that's built when you call << on a hmt association. I0ve written up a test-case and noticed that there could be more hidden errors:

  def test_include?
    ActiveRecord::Base.logger = Logger.new(STDOUT)
    person = Person.new(first_name: "Peter")
    post = Post.new(title: "Cats & Dogs", body: "are pets")

    person.posts << post
    # assert person.posts.include?(post)

    person.posts.delete(post)
    # assert_not person.posts.include?(post), "should not contain the post after deletion but did."

    person.save!
    # assert_not person.posts.include?(post)
  end

This leads to the following SQL statements:

D, [2013-03-05T13:39:19.470303 #5926] DEBUG -- :   SQL (0.2ms)  INSERT INTO "people" ("created_at", "first_name", "updated_at") VALUES (?, ?, ?)  [["created_at", 2013-03-05 12:39:19 UTC], ["first_name", "Peter"], ["updated_at", 2013-03-05 12:39:19 UTC]]
D, [2013-03-05T13:39:19.473836 #5926] DEBUG -- :   SQL (0.1ms)  INSERT INTO "posts" ("body", "title") VALUES (?, ?)  [["body", "are pets"], ["title", "Cats & Dogs"]]
D, [2013-03-05T13:39:19.474598 #5926] DEBUG -- :   SQL (0.1ms)  INSERT INTO "readers" ("person_id", "post_id") VALUES (?, ?)  [["person_id", 5], ["post_id", 12]]

The post was not inserted but the Reader that was built is. Is this the expected behavior?

@carlosantoniodasilva @rafaelfranca what do you think?

vipulnsward added a commit to vipulnsward/rails that referenced this issue Nov 30, 2013
When target record is deleted then in-memory association
record should be deleted for hm:t case.

Fixes rails#9548.
@RKushnir RKushnir added the stale label Apr 23, 2014
@rafaelfranca
Copy link
Member

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

@nerdinand
Copy link
Contributor

I tried to reproduce this on master. It still seems to be a problem:
https://gist.github.com/nerdinand/7665496e2b6d26619781

@senny senny added the pinned label Mar 25, 2015
@nerdinand
Copy link
Contributor

Proposed patch still works. Should I send a new PR?

@kamipo
Copy link
Member

kamipo commented Jan 20, 2018

Fixed by #29593.

@kamipo kamipo closed this as completed Jan 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants