This project is archived and is in readonly mode.
Unable to create has_one association within after_initialize of nested belongs_to association
Reported by feldercarb | April 9th, 2010 @ 06:52 AM
When following an after_initialize chain through multiple layers of an object hierarchy, has_one associations created within a belongs_to association do not remain in the object hierarchy when returning up the chain.
The following classes are from the associated test case:
class Book < ActiveRecord::Base
has_many :stories
def after_initialize
stories.build( :book => self ) if stories.empty?
end
end
class Story < ActiveRecord::Base
belongs_to :book
belongs_to :author
def after_initialize
build_author if author.nil?
end
end
class Author < ActiveRecord::Base
has_one :profile
def after_initialize
build_profile if profile.nil?
end
end
class Profile < ActiveRecord::Base
belongs_to :author
end
If the above objects are defined, then creating a new Book will fire all after_initialize methods and we should end up with a Book with one Story attributed to one Author who has one Profile
Stepping through the methods proves that the Author.after_initialize creates the Profile, but when we return to the Story level, the Author does not have the created Profile.
Therefore the test case:
class BookTest < ActiveSupport::TestCase
test "book has author profiles" do
b = Book.new
assert_not_nil b.stories.first.author.profile, "Author profile is missing"
end
end
will fail when it should succeed.
Comments and changes to this ticket
-
feldercarb April 9th, 2010 @ 03:56 PM
I have a temporary work-around for this which requires the removal of all after_initialize methods and calling the after_initialize functionality manually.
If you go in and change all of the after_initialize methods to something like "build_associations", then call the build_association methods after each object is created, and chain the build_associations methods, it works.
So if we change the models from the first report to:
class Book < ActiveRecord::Base has_many :stories def build_associations s = stories.build( :book => self ) if stories.empty? s.build_associations end end class Story < ActiveRecord::Base belongs_to :book belongs_to :author def build_associations build_author if author.nil? author.build_associations end end class Author < ActiveRecord::Base has_one :profile def build_associations build_profile if profile.nil? end end
The test will succeed. (See attached belongstoafterinitializefailureworking.tgz file for full app)
I don't know the full reasoning behind this except that we are not inside the framework's object initialization process when we initialize the associations.
-
Santiago Pastorino February 2nd, 2011 @ 04:44 PM
- State changed from new to open
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 core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino February 2nd, 2011 @ 04:44 PM
- State changed from open to stale
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>