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.

child/grandchild associations reload from db after nested attributes assignment

#5053

When validating fails on updating record by nested attributes, the child/grandchild associations collection will be reload from database.

  @ship = Ship.create!(:name => "The good ship Dollypop")
  @part = @ship.parts.create!(:name => "Mast")
  @trinket = @part.trinkets.create!(:name => "Necklace")

  @ship.attributes = {:name => nil, :parts_attributes => [{:id => @part.id, :name => 'Deck', :trinkets_attributes => [{:id => @trinket.id, :name => "Ruby"}]}]}
  @ship.save

Then

@ship.parts.first.name == "Mast"
@ship.parts.first.trinkets.first.name == "Necklace"

Reported by szetobo · July 6th, 2010 @ 12:10 PM

State: resolved
Milestone: 2.3.9
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. Neeraj Singh
    Neeraj Singh
    • State changed from new to open
    • Tag changed from nested attributes to nested attributes, rails3
    • Importance changed from to Low

    This is what's happening based on my analysis. Here is how I setup the models.

    ActiveRecord::Schema.define(:version => 20100706145311) do
      create_table "ship_parts", :force => true do |t|
        t.string  "name"
        t.integer "ship_id"
      end
      create_table "ships", :force => true do |t|
        t.string "name"
      end
    end
    
    class Ship < ActiveRecord::Base
      has_many :parts , :class_name => 'ShipPart'
      accepts_nested_attributes_for :parts, :allow_destroy => true
    
      validates_presence_of :name
    
      def self.lab
        @ship = Ship.create!(:name => "The good ship Dollypop")
        @part = @ship.parts.create!(:name => "Mast")
        @ship.reload
        @ship.attributes = {:name => nil, :parts_attributes => [{:id => @part.id, :name => 'Deck' }]}
        @ship.save
        puts @ship.parts.first.name
        #puts @ship.parts[0].name
      end
    
    end
    class ShipPart < ActiveRecord::Base
      belongs_to :ship
      validates_presence_of :name
    end
    

    First thing is that we need to have @ship.reload. without that @ship thinks that children are already loaded and never really looks into the updated children values.

    Second thing is that when you invoke @ship.parts.first.name rails invokes a query to the database even if @ship.parts is already loaded. In order to inquire about the loaded child you need to do
    puts @ship.parts[0].name .

    And with these two changes a) @ship.reload and b)@ship.parts[0].name you get 'Deck' as the final output.

    I do think that @ship.reload issue should be fixed. Looked at code but not sure where to fix. I am marking this ticket as open because of the reload issue. Someone else might know the fix.

    July 7th, 2010 @ 04:53 AM

  2. szetobo
    szetobo

    If I call reload before assigning attributes, it seems that @ship.parts[0].name and @ship.parts.first.name behave the same. You are correct that the issue is related to reloading association before nested attributes assignment.

    July 7th, 2010 @ 07:44 AM

  3. Subba
    Subba

    it is nothing to do with validation failure.

    it is due optimization present in nested_attributes.

    if you look into nested attributes line 358 (nested_attributes.rb)

    
          existing_records = if association.loaded?
            association.to_a
          else
            attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact
            attribute_ids.present? ? association.all(:conditions => {association.primary_key => attribute_ids}) : []
          end
    

    from above code snippet nested attributes will only select objects if the association is not loaded
    but partially selecting ids will not cause loaded flag to be set in association_collection

    so any subsequent call to association after update_attributes will
    load_target will trigger call database wiping out all the association changes except new records line number 391) association_collection.rb

    below is 2-3-8 version of load target

    
          def load_target
              if !@owner.new_record? || foreign_key_present
                begin
                  if !loaded?
                    if @target.is_a?(Array) && @target.any?
                      @target = find_target + @target.find_all {|t| t.new_record? }
                    else
                      @target = find_target
                    end
                  end
                rescue ActiveRecord::RecordNotFound
                  reset
                end
              end
    
              loaded if target
              target
            end
    

    2-3-stable version fixes this

    
          def load_target
              if !@owner.new_record? || foreign_key_present
                begin
                  if !loaded?
                    if @target.is_a?(Array) && @target.any?
                      @target = find_target.map do |f|
                        i = @target.index(f)
                        t = @target.delete_at(i) if i
                        if t && t.changed?
                          t
                        else
                          f.mark_for_destruction if t && t.marked_for_destruction?
                          f
                        end
                      end + @target
                    else
                      @target = find_target
                    end
                  end
                rescue ActiveRecord::RecordNotFound
                  reset
                end
              end
    

    July 7th, 2010 @ 02:00 PM

  4. Neeraj Singh
    Neeraj Singh

    thanks for the explanation Subba. That's some complicated code.

    July 7th, 2010 @ 02:14 PM

  5. Neeraj Singh
    Neeraj Singh

    I still think that we should not have to reload to get the right behavior.

    @part = @ship.parts.create!(:name => "Mast")
    

    From the above code one can't be sure if parts is part of nested_attributes or a simple has_many. However if it is part of nested_attributes then @ship.reset (or something equivalent ) should be called so that later operations do not interfere with already loaded children.

    July 7th, 2010 @ 02:19 PM

  6. szetobo
    szetobo
    • Title changed from child/grandchild associations reload from db upon validation error for nested attributes to child/grandchild associations reload from db after nested attributes assignment

    I agree with Neeraj that it should not need to reload before every nested_attributes assignment. It is sometimes very difficult to issue reload statement for every associations as the relationship can be few levels deep involving 10+ associated objects.

    Actually direct update through association proxy should have the same effect as nested_attributes assignment. Should the association be loaded before nested_attributes assignment, i.e. replace the code segment with

    existing_records = if association.loaded?
      association.to_a
    else
      attribute_ids = attributes_collection.map {|a| a['id'] || a[:id]}.compact
      attribute_ids.present? association.all(:conditions => {association.primary_key => attribute_ids}) : []
    end
    

    with

    existing_records = (association.loaded? ? association.to_a : association.all)
    

    Not sure this change has any other side effect but the test case passed without any compliant.

    BTW, when I look carefully into the existing test case about nested_attributes, I find that the use of send(:load_target). It seems solve the problem I'm facing. I just need to make function call as:

    @ship.parts.send(:load_target).first.name
    @ship.parts.send(:load_target).first.trinkets.send(:load_target).first.name
    

    It is a bit clumsy but it works. However :load_target is a protected method, although send() can bypass to invoke it, it seems not a good practice to call it from our application, right?!

    July 8th, 2010 @ 07:52 AM

  7. Neeraj Singh
    Neeraj Singh
    • Assigned user set to Neeraj Singh

    @szetobo thanks for the investigation. Which version of rails you are working with.

    Just to let you know nested_attributes in rails 2.3.8 is totally broken. Also there are unexplained differences between rails edge version and rails 2-3-stable version.

    Just looking at the code it seems some edge cases like new_record etc have been missed out.

    We are in the process of writing detailed test cases for both 2-3-stable and rails edge. And then hopefully the code fix should resolve some of the issues mentioned in this thread.

    Will update this thread when we have more details.

    July 8th, 2010 @ 11:25 AM

  8. Neeraj Singh
    Neeraj Singh

    Some discussion regarded nested_attribute took place on #4830 . So just mentioning that ticket here in case someone wants to get full picture.

    July 8th, 2010 @ 11:34 AM

  9. szetobo
    szetobo
    • Assigned user cleared.

    I'm working on edge version. Nested attributes for edge version also broken badly. Apps migrate from 2.3.5 just broken without major code changes, especially on nested_attributes part.

    I'll submit another test case shortly about duplicate entry on the association collection with same id right after nested_attributes assignment. Hope that can help a little bit to speed up the debugging process.

    Anyway, thanks for looking into the issue.

    July 8th, 2010 @ 11:52 AM

  10. szetobo
    szetobo
    • Assigned user set to Neeraj Singh

    July 8th, 2010 @ 11:53 AM

  11. Eloy Duran
    Eloy Duran

    Forgive me if I missed anything, but the reason you can use methods like #first on a collection association without the full collection being loaded first, is because #first doesn't cache the object. Thus, if its values are updated/marked for destruction, then autosave won't find the object in the ‘target’ when save time comes.

    This is why in the tests I explicitly load the target first. (In other tests they used #class to make sure the target was loaded, I opted for the private but more declarative load_target.)

    The only way to make using #first, without first loading the complete target, work would be to finally have a full identity map, and NOT replace objects already loaded through #first.

    I did make a patch for this once, but since it's not a full identity map it was rejected, which I agreed with in the end. Someone that really needs this should simply sit down and implement a proper identity map.

    Finally, autosave does NOT need this behavior for nested attributes, because nested attributes operates on the loaded target, or loads it. It does NOT use #first.

    HTH

    July 8th, 2010 @ 12:50 PM

  12. Neeraj Singh
    Neeraj Singh

    Attached is a test patch which really tests the intent.

    July 8th, 2010 @ 04:11 PM

  13. Neeraj Singh
    Neeraj Singh

    @Eloy I am looking at the tests and it is full of @ship.reload._do_something.

    The reason why this ticket was opened gets resolved is user does a model.reload after populating children but before starting nested_attributes activities.

    Is there a way to get the whole thing working without forcing one to do reload because while working in rails console this is not the most intuitive thing to do. I am looking into it but so far no luck.

    Thanks

    July 8th, 2010 @ 06:17 PM

  14. Eloy Duran
    Eloy Duran

    @Neeraj Well, I can think of two options. Either create/merge a patch like the one I mentioned earlier: #1751.

    Or add something like this to your ~/.irbrc, because I'm assuming that's really the only place one would use #first in combination with autosave:

    if defined?(ActiveRecord)
      class ActiveRecord::AssociationCollection
        alias_method :first_before_load_target, :first
        def first(*args)
          load_target
          first_before_load_target(*args)
        end
      end
    end
    

    Effectively always loading the target when in the console. (Don't forget to do the same for #last.)

    July 8th, 2010 @ 06:31 PM

  15. Eloy Duran
    Eloy Duran

    I hope I got the class etc right, I haven't looked at AR internals for a while :)

    July 8th, 2010 @ 06:32 PM

  16. Neeraj Singh
    Neeraj Singh

    Thanks Eloy.

    I will take a look at #1751 and the other option you suggested. In the meantime wanted to add that without that reload both of the following cases do not work. Just to clear the air that it is not just about 'first'.

    puts @ship.parts[0].name
    puts @ship.parts.name
    

    July 8th, 2010 @ 07:11 PM

  17. Neeraj Singh
    Neeraj Singh

    @szetobo I believe we have a fix for this issue.

    My buddy is going to upload the fix in a moment. However since .first gets the data from the database I would suggest you to update your test. A fixed version might look something like this http://pastie.org/1036943 .

    July 9th, 2010 @ 03:18 AM

  18. Subba
    Subba

    attached is code fix.

    This is what is currently happening.

    • a new @ship record is created.
    • @ship.parts.create(:name => 'part_name') creates a new part in the database. However this @part instance is added to @target. Note that @ship.parts.loaded? is NOT set to true.
    • next nested_attributes assignment happens
    • rails gets existing_records by pulling data from the database for the @part.id
    • next assocation.send(:add_record_to_target_with_callbacks, existing_record) unless association.loaded?
    • when above code is executed then the database representation of @part gets added to @target.
    • so the end result is that @target ends up with two different instances of same @part.
    • everything goes downhill from there

    If I explained the problem correctly then fix should be obvious. And that is not to add to @target if @target already has an instance of same @part. My fix replaces the instance held by @target with new instance.

    I am attaching patch for both 2-3-stable and rails edge.

    July 9th, 2010 @ 03:32 AM

  19. Neeraj Singh
    Neeraj Singh

    Attached is patch which strengthens the test cases further and it has minor code refactoring.

    July 9th, 2010 @ 03:52 AM

  20. szetobo
    szetobo

    The patch work!! Thanks so much for the prompt responses. It is a show stopper in our project and now it is gone.

    I've updated the test case in a way that help me understand the effect of different way to access the data. A funny finding is that even target[0] & target.first is a little bit difference internally, the association @target seems already catered and the result is consistency no matter it is access through [] or .first. In the test case, I added a lot of checking assertion to see when the association get loaded and will the load target respect partial loaded subset produced by nested attributes assignment. It just work as expected.

    I agree that the identity map Eloy mention is a better solution as a whole, but since it is not yet there and still sometime before it will be added into the code base, I have to live with a workable solution at this moment.

    Looking forward to get this patch commit into the edge master.

    July 9th, 2010 @ 07:57 AM

  21. szetobo
    szetobo

    Sorry, forgot to include the test case fyr.

    July 9th, 2010 @ 07:57 AM

  22. James Le Cuirot
    James Le Cuirot

    Neeraj, your "refactoring" of my changes in load_target doesn't have the same behaviour. If a record is marked for destruction but otherwise unchanged, it should use the newly fetched record and mark that for destruction.

    July 9th, 2010 @ 09:15 AM

  23. Neeraj Singh
    Neeraj Singh

    @James I agree that as per my code change the old record would be marked for destruction and not the newly fetched one. However does that really matter? In the end an existing record is marked for destruction and that's what counts. However I am not averse to reverting back to the way code was.

    Thanks.

    July 9th, 2010 @ 10:41 AM

  24. James Le Cuirot
    James Le Cuirot

    If the changes aren't saved due to a validation error and the form is redisplayed in such a way that you can still see some details about the record to be deleted, I think it would be worthwhile showing the most up-to-date details about that record in case someone else has changed it in the meantime. You may then decide not to delete it after all. Both approaches would work sufficiently but given the choice, I think I prefer this one.

    July 9th, 2010 @ 11:01 AM

  25. Neeraj Singh
    Neeraj Singh

    makes sense. I will revert my changes. Thanks for the feedback.

    July 9th, 2010 @ 11:05 AM

  26. Neeraj Singh
    Neeraj Singh
    • Milestone set to 3.x

    attached is modified test patch.

    July 9th, 2010 @ 11:10 AM

  27. szetobo
    szetobo

    What should I do to make my rails app reference the latest rails source directory, including the patch, instead of the gem installed on my system. Just want to try it out before the patch has been commit into the master head.

    (I know it may not be the right place to ask a question like this, but most of the post I've searched seems outdated and not working.)

    July 10th, 2010 @ 06:13 AM

  28. Neeraj Singh
    Neeraj Singh

    In your Gemfile comment out the beta reference to rails and refer to git version.

    #gem 'rails', '3.0.0.beta4'
    gem 'rails', :git => 'git://github.com/rails/rails.git'
    

    Then run following command and you will have rails edge in your vendor/bundler directory.

    bundle install vendor --disable-shared-gems
    

    July 10th, 2010 @ 08:30 AM

  29. szetobo
    szetobo

    Thanks a lot, really appreciate that.

    July 10th, 2010 @ 08:40 AM

  30. Subba
    Subba

    updating patch with optimized code and test.

    July 10th, 2010 @ 05:34 PM

  31. Neeraj Singh
    Neeraj Singh
    • Assigned user changed from Neeraj Singh to José Valim
    • Tag changed from nested attributes, rails3 to nested attributes, patch

    July 10th, 2010 @ 05:44 PM

  32. szetobo
    szetobo

    I've found another problem when applied the patch into my app. It happens when Parts doesn't change and one of its Trinket has updated, the changes on Trinket will be replaced with db image when part.trinkets reload. That's because load_target of association_collection will only retain @target record when it has been changed, otherwise it will be replaced by a freshly loaded record form db. Doing so will wipe out the next level associations collection, if any, and that's caused the problem.

    I've attached a patch with additional fix which alter load_target in order to maintain the loaded record with its unchanged attributes updated by the freshly load instance return by find_target. An additional test case has been added as well to guard against this case.

    test "if association is not loaded and child doesn't change and I am saving a grandchild then in memory record should be used" do
      @ship.parts_attributes=[{:id => @part.id,:trinkets_attributes =>[{:id => @trinket.id, :name => 'Ruby'}]}]
      assert_equal 1, @ship.parts.proxy_target.size
      assert_equal 'Mast', @ship.parts[0].name
      assert_equal 1, @ship.parts[0].trinkets.proxy_target.size
      assert_equal 'Ruby', @ship.parts[0].trinkets[0].name
    end
    

    During the testing by running my app on top of the rails patch installed into vendor/bundle, I found that rails framework doesn't reload automatically if source code updated. So that a server restart is needed on every code change attempt, anything to do with this situation, or is it a limitation that can't be solved currently?

    July 11th, 2010 @ 11:28 PM

  33. Neeraj Singh
    Neeraj Singh

    @szetobo your patch looks good. However I will spend some more time tomorrow testing it.

    Could you please attach your patch again in such a manner that you do not include the code provided by Subba. In this way Subba will get credit for the work he has done and you would get credit for the work your work.

    Thanks

    July 12th, 2010 @ 12:29 AM

  34. szetobo
    szetobo

    Here's the patch. Thanks a lot.

    July 12th, 2010 @ 03:11 AM

  35. szetobo
    szetobo

    Sorry for my careless mistake. Here's another minor fix for excluding "id" when copying attributes in the load_target of association_collection.rb. Otherwise WARNING: Can't mass-assign protected attributes: id will blow up in the log.

    July 12th, 2010 @ 09:37 AM

  36. Neeraj Singh
    Neeraj Singh

    I am not able to follow the logic of removing this line

    f.mark_for_destruction if t && t.marked_for_destruction?
    

    July 12th, 2010 @ 09:08 PM

  37. James Le Cuirot
    James Le Cuirot

    Please don't remove that line.

    July 12th, 2010 @ 09:57 PM

  38. Neeraj Singh
    Neeraj Singh

    I have not run the tests. However if all tests are passing after removing that line the I would add a test for that case.

    July 12th, 2010 @ 09:59 PM

  39. szetobo
    szetobo

    f.mark_for_destruction is need in original code segment because f will be used instead of t if t && t.changed?. As I stated above, doing so will remove all association collection of t, if any, even if t.changed? is false.

    The latest patch will not replace t but will update attributes from db, so if t already mark_for_destruction, it will still marked. For f freshly loaded from db, mark_for_destruction should be cleared. Therefore I just remove this line from my patch. I've run all the test in nested attribute test case and all passed without failure. Please let me know if my understanding is correct or not.

    July 13th, 2010 @ 02:42 AM

  40. James Le Cuirot
    James Le Cuirot

    That sounds okay except that marked_for_destruction isn't an attribute, it's an instance variable.

    July 13th, 2010 @ 09:05 AM

  41. Subba
    Subba

    szetobo's changes propogating the changes to destroyed records below test case proves this.
    his code is much shorter than current code.

    
      test "if association is loaded before saving parent destroyed in memory children should be destroyed" do
          @ship.parts_attributes=[{:id => @part.id,:_destroy =>'1'}]
          @part.update_attribute(:name, 'Deck')
          assert @ship.parts.proxy_target[0].marked_for_destruction?
          assert_equal 'Deck', @part.name
    
          @ship.parts.to_ary
    
          assert @ship.parts[0].marked_for_destruction?
          assert_equal 'Deck', @part.name
    
          @ship.save
          assert_nil ShipPart.find_by_id(@part.id)
        end
    

    July 13th, 2010 @ 11:28 AM

  42. Subba
  43. Subba
    Subba

    ignore the last one here is the better patch

    July 15th, 2010 @ 04:03 AM

  44. Neeraj Singh
    Neeraj Singh

    There has been a lot of patches attached to this ticket to the point where it is starting to get a bit confusing.

    I have consolidated all the patches and have applied them on my forked branch of rails.

    Please take a look at http://github.com/neerajdotname/rails/commits/ticket_5053 . Last 4 committs are related to this ticket.

    Please have a look and do chime in with your thoughts.

    once again in the forked copy look for branch ticket_5053 .

    thanks everyone.

    July 15th, 2010 @ 04:54 AM

  45. szetobo
    szetobo

    Thanks Neeraj for organize the patches submitted so far. May I know what is missing before the patches will be committed into edge? Thanks again for everyone.

    July 15th, 2010 @ 07:38 AM

  46. Neeraj Singh
    Neeraj Singh

    @Eloy Duran and @James Le Cuirot : Could you +1 the work done so far at http://github.com/neerajdotname/rails/commits/ticket_5053 (last 4 comitts) so that we could be sure that patches make sense.

    @szetobo once we have the sign off from them then it would be committed to edge.

    July 15th, 2010 @ 09:37 AM

  47. Eloy Duran
    Eloy Duran

    Sure thing, added comments to each commit.

    July 15th, 2010 @ 11:17 AM

  48. James Le Cuirot
    James Le Cuirot

    Sorry if I'm holding this up but I'd like a chance to review this. I'll try to do it tomorrow.

    July 15th, 2010 @ 11:34 PM

  49. Neeraj Singh
    Neeraj Singh

    Eloy provided his comments on committs. Tonight I will work on his feedback and will provide a new codebase to look at. So hold your review until I post a new link.

    thanks

    July 16th, 2010 @ 01:38 AM

  50. Neeraj Singh
    Neeraj Singh

    Feedback provided by Eloy has been incorporated at a new branch http://github.com/neerajdotname/rails/commits/5053_v4 .

    Please take a look at last 4 committs in that branch and provide your feedback.

    July 19th, 2010 @ 02:38 AM

  51. Eloy Duran
  52. Neeraj Singh
    Neeraj Singh
    • Tag changed from nested attributes, patch to nested attributes, rails 3, patch

    I have pushed a new branch (again) http://github.com/neerajdotname/rails/commits/5053_v5 . This has feedback provided by Eloy.

    Eloy: thanks for all your feedback.

    szetobo: I made two minor changes to the test file you had attached. Both were based on the feedback provided by Eloy. I have retained you as the author of the commit.

    Others please take a look at the above mentioned branch. Let's try to wrap it up soon. :-)

    July 19th, 2010 @ 08:54 PM

  53. szetobo
    szetobo

    Look good, I admitted that assert_no_difference has better semantic than assert_equal.

    Neeraj: It doesn't matter you retained me as the author or not, I just want the issue fixed because it is a show stopper to us. I really appreciate the work done so far by rails community. My work just so minor and can't really compare to what I have got from it.

    July 20th, 2010 @ 02:42 AM

  54. Neeraj Singh
    Neeraj Singh

    @szetobo I believe we are quite close to finish line :-)

    A few more eyes , a few +1 and it will be good to go.

    July 20th, 2010 @ 02:48 AM

  55. James Le Cuirot
    James Le Cuirot

    Made one minor comment but okay other than that. I realise now that my earlier comment about marked_for_destruction being an instance variable doesn't actually apply.

    July 20th, 2010 @ 10:53 PM

  56. Eloy Duran
    Eloy Duran

    Left some feedback on http://github.com/neerajdotname/rails/commit/49cc2d682f17dcf74e11b5....

    As a final note, it seems that some of these patches are written because of an issue encountered when using nested attributes. However, they are not specifically about nested attributes. For instance the one mentioned above, which is really about association collection. So I would expect at least a test added to the association collection test, and maybe a regression one to the nested attributes tests. I especially was a bit surprised to find that there are a whole bunch of these ‘lost’ tests in the nested attributes tests.

    All tests from line 811 down should not be there at all: http://github.com/neerajdotname/rails/blob/49cc2d682f17dcf74e11b56c...

    They should either be in the autosave association tests, or in the association collection tests, as far as I have studied them. Furthermore, they should not use the nested attributes API, as again, it's unrelated and only adds noise.

    Having said that, I think the patches can go in. But I would appreciate a test refactoring next, improving the descriptions and moving them to the correct test file.

    July 21st, 2010 @ 11:24 AM

  57. Repository
    Repository
    • State changed from open to resolved

    (from [c0bfa0bfc17f4aa615cd9d1006509e0d84b5692d]) In nested_attributes when association is not loaded and association record is saved and then in memory record attributes should be saved

    [#5053 state:resolved]

    Signed-off-by: José Valim jose.valim@gmail.com
    http://github.com/rails/rails/commit/c0bfa0bfc17f4aa615cd9d1006509e...

    July 21st, 2010 @ 01:26 PM

  58. Repository
    Repository

    (from [0057d2df71ec7c2a788acd3b4bade263fc0fe361]) association load target shouldn't replace records from db if it is already loaded by nested attributes assignment

    [#5053 state:resolved]

    Signed-off-by: José Valim jose.valim@gmail.com
    http://github.com/rails/rails/commit/0057d2df71ec7c2a788acd3b4bade2...

    July 21st, 2010 @ 01:26 PM

  59. Neeraj Singh
    Neeraj Singh
    • State changed from resolved to open

    http://github.com/neerajdotname/rails/commits/5053_v5 is getting committed. I am going to create two more tickets.

    • for uniq change : In that ticket I would post all the discussions that happened on my personal branch. Do not want to lose the history. And then we will commit the uniq change.

    • second ticket would be to take care of tests refactoring Eloy mentioned.

    July 21st, 2010 @ 01:28 PM

  60. Neeraj Singh
    Neeraj Singh
    • State changed from open to resolved

    July 21st, 2010 @ 01:29 PM

  61. Eloy Duran
    Eloy Duran

    @Neeraj Thanks for your continued work :)

    July 21st, 2010 @ 02:09 PM

  62. Neeraj Singh
    Neeraj Singh

    Two tickets have been created as follow up tasks. Please follow these tickets if you are interested.

    #5171

    #5170

    July 21st, 2010 @ 02:52 PM

  63. Neeraj Singh
    Neeraj Singh
    • Assigned user changed from José Valim to Neeraj Singh
    • State changed from resolved to open
    • Tag changed from nested attributes, rails 3, patch to nested attributes, patch
    • Milestone changed from 3.x to 2.3.9

    Given that nested_attributes is totally broken in 2.3.8 and 2-3-stable has fixes for nested_attributes, I would say that some part of the fix should go to 2-3-stable too. Subba is working on backporting some part of the fix.

    Marking the milestone as 2.3.9 and assigning it to myself until the patch is ready.

    July 21st, 2010 @ 03:15 PM

  64. Subba
    Subba

    i am attaching 2-3-stable patch. neeraj can you verify it.

    July 23rd, 2010 @ 02:56 AM

  65. Neeraj Singh
    Neeraj Singh
    • Assigned user changed from Neeraj Singh to José Valim

    patch for 2-3-stable looks good. All tests are passing.

    +1

    July 23rd, 2010 @ 09:43 PM

  66. Repository
    Repository
    • State changed from open to resolved

    (from [12bbc34aca509aba5032e8cc8859ef0c0c845cca]) In nested_attributes when association is not loaded and association record is saved then in memory record attributes should be saved

    [#5053 state:resolved]

    Signed-off-by: José Valim jose.valim@gmail.com
    http://github.com/rails/rails/commit/12bbc34aca509aba5032e8cc8859ef...

    August 3rd, 2010 @ 09:57 AM

  67. Josh Goebel
    Josh Goebel

    Since upgrading to 2.3.9 I have this errors when I try and do some simple things with collections:

    NoMethodError: undefined method `keys' for false:FalseClass
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:357:in `load_target'
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:356:in `tap'
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:356:in `load_target'
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:353:in `map'
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:353:in `load_target'
        development/ruby/1.8/gems/activerecord-2.3.9/lib/active_record/associations/association_collection.rb:149:in `delete_all'
        test/unit/assignment_test.rb:127:in `__bind_1283838340_803300'
    

    TEST CODE

    Line # 127: up.assignments.delete_all
    

    MODEL CODE

    has_many :assignments, :dependent => :delete_all

    Another example that causes the same error in the same place:

    return unless self.assignments.any? { |x| x.changes? and x.user_id == current_user.id }
    

    Same exact error... I'm posting to this ticket since the error falls inside it's changes... and this was not an issue on 2.3.8. Seems t.changes is returning true/false instead of a hash?

    September 7th, 2010 @ 07:01 AM

  68. Josh Goebel
    Josh Goebel

    Ah, changes is reserved (dirty tracking, duh)... and my model has a changes column... hasn't hurt anything until now because I guess Rails itself was not dependent on the changes column and after this update it is.

    My problem to go and fix. :)

    September 7th, 2010 @ 07:23 AM

  69. Jeff Kreeftmeijer
    Jeff Kreeftmeijer
    • Tag cleared.

    Automatic cleanup of spam.

    November 8th, 2010 @ 08:54 AM