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

fix issue in #reify_has_many_through #596

Merged
merged 1 commit into from
Sep 16, 2015

Conversation

theRealNG
Copy link
Contributor

Fix for #590

The assoc.foreign_key holds true only when the association is as follows

Book
has_many :authorships
has_many :authors, :through => :authorships

Authorships
belongs_to :book
belongs_to :author

Author
has_many :authorships
has_many :books, :through => :authorships

In this case the assoc.foreign_key and assoc.association_foreign_key are the same

But in the case of the following associations

Document
has_many :sections
has_many :paragraphs, :through => :sections

Section
belongs_to :document
has_many :paragraphs

Paragraph
belongs_to :section

the assoc.foreign_key and assoc.association_foreign_key are different and assoc.association_foreign_key gets the correct list of associated foreign_keys for the model.

For Ref: http://www.rubydoc.info/docs/rails/3.0.0/ActiveRecord%2FReflection%2FAssociationReflection%3Aassociation_foreign_key

EDIT:
When a nested has_many relation is present, using the "reify_has_manys" method to reify the has_many through associations.

@jaredbeck
Copy link
Member

Thanks for the PR! Can you add a test that demonstrates the issue?

@jaredbeck
Copy link
Member

Can you add a test that demonstrates the issue?

Just to clarify, we know that #590 is a confirmed bug, but it'd still be nice to have a test. Thanks.

@theRealNG
Copy link
Contributor Author

Ya sure. Will work on it.

@jaredbeck
Copy link
Member

You should be able to use the failing test I already wrote (https://github.com/jaredbeck/pt_issue_590/blob/de54892426966d146a13c8c2382735826aa76660/spec/model/document_spec.rb) as a starting point.

@jaredbeck jaredbeck mentioned this pull request Aug 31, 2015
@theRealNG theRealNG force-pushed the issue#590 branch 8 times, most recently from d4e4271 to aaac0ea Compare September 2, 2015 20:21
@chapter.sections.first.update_attributes :name => "section 3"
end

context "when reified is called" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is called reify, not reified. Please update the context string here.

@jaredbeck
Copy link
Member

@theRealNG this is looking good. I appreciate how thorough you were with the tests. My comments are mostly about style. I'm trying my best to understand the meat of the change, but I'd really like to get Ben's opinion as he is more familiar with the reify functions.

CC: @batter

@theRealNG
Copy link
Contributor Author

Bug:
We are not handling nested has_many associations.

Fix:
For a nested has_many associations we can call "has_manys" method for each of the nested associations so that we handle any levels of nesting.

Explanation with example :-

  • A chapter has many sections and a section has many paragraphs.
  • So when we call "reify_has_many_directly" on the chapter object, we get a list of sections that are associated with the chapter.
  • Since the association between section and paragraphs is also a has_many association, we can call reify_has_many_directly on each of the sections we got from the above result to get all the paragraphs associated to that section and in turn associated to the chapter.

But i'm calling "reify_has_manys" on each section so that we can handle any levels of nesting.
(ex:- A chapter has_many sections, A section has_many paragraphs and a paragraph belongs_to a source)

return
end

collection_keys = through_collection.map { |through_model| through_model.send(assoc.association_foreign_key)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I revert the change to this one line, by calling assoc.foreign_key instead of assoc.association_foreign_key, all the tests still pass. So, is it necessary to change this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the example of Document, Sections and paragraphs:
The through_model is a object of Section.

What we are trying to do is get the list of all the paragraphs associated to the section by calling:
section.paragraph_ids

If we do Section.reflect_on_association(:paragraphs).foreign_key, it returns 'section_id' and if we do Section.reflect_on_association(:paragraphs).association_foreign_key, it returns 'paragraph_id'. So we should be using 'association_foreign_key' instead of 'foreign_key'.

This was not an issue so far because in a 'belongs_to' association assoc.association_foreign_key and assoc.foreign_key are the same.

Even if you replace assoc.association_foreign_key with assoc.foreign_key it works because there is no chance of 'has_many' associations to hit the line because we are calling 'return' on line:424

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That all makes sense, thanks.

@jaredbeck jaredbeck added this to the 4.1.0 milestone Sep 13, 2015
@jaredbeck
Copy link
Member

Ben, I think this is ready to merge, now that it includes theRealNG#1

What do you think?

@theRealNG
Copy link
Contributor Author

Do you want me to squash the commits into a single commit?

@jaredbeck
Copy link
Member

Do you want me to squash the commits into a single commit?

Sure, thanks.

@batter
Copy link
Collaborator

batter commented Sep 16, 2015

👍 Nice work, thanks to both of you.

My take is it's fine to leave it as a split commit as long as the merge has no fast forward but I don't care

@batter
Copy link
Collaborator

batter commented Sep 16, 2015

@jaredbeck Did the test we wrote ever end up working out of curiosity?

@jaredbeck
Copy link
Member

@jaredbeck Did the test we wrote ever end up working out of curiosity?

Yes, see theRealNG#1

jaredbeck added a commit that referenced this pull request Sep 16, 2015
fix issue in #reify_has_many_through
@jaredbeck jaredbeck merged commit 364d04a into paper-trail-gem:master Sep 16, 2015
@batter
Copy link
Collaborator

batter commented Sep 16, 2015

So what is our merge process now for these types of things @jaredbeck?

Merge to master, then cherry-pick / backport to 4.1-stable, 4.1-stable?

@jaredbeck
Copy link
Member

So what is our merge process now for these types of things?
Merge to master, then cherry-pick / backport to [4.0-stable], 4.1-stable?

Yes, that's how I picture it working. I think it's a common strategy; it's what rails seems to do. One thing I'm not sure of is how to run CI for a backport. I guess we could do a PR for each backport..

@batter
Copy link
Collaborator

batter commented Sep 17, 2015

ok that sounds good, just wanted to be clear about how you were envisioning it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants