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.

AR#find_or_create doesn't add the created model to collection

#2211

While Company has many Clients, and if a new client created by


new_client = a_company.clients_find_or_create_by_name

the new_client is not dynamically added to


a_company.clients

until you run


a_company.clients :reload

This behaviour differs from simple


a_company.clients.create

Is n't it very annoying?

Reported by Akira Matsuda · March 11th, 2009 @ 11:40 AM

State: stale
Milestone: 3.x
Assigned to: Jeremy Kemper Jeremy Kemper
Importance: none

Activity

  1. David Medinets
    David Medinets

    I have verified this behavior by creating a new application with a failing test case:

    script/generate rspec_model company name:string script/generate rspec_model client company_id:integer name:string

    Then I added the associations:

    class Company < ActiveRecord::Base has_many :clients end

    class Client < ActiveRecord::Base belongs_to :company end

    Here is a failing test case;

    require File.expand_path(File.dirname(FILE) + '/../spec_helper') require 'stringio'

    def redirect orig_defout = $stdout $stdout = StringIO.new yield $stdout.string ensure $stdout = orig_defout end

    describe Company do it "output size from company.clients should double after two clients are created" do

    company = Company.create! :name => 'AAA'
    company.clients.find_or_create_by_name :name => 'client_A01'
    eval_string = 'p company.clients'
    output_string = redirect { eval eval_string }
    first_size = output_string.size
    company.clients.find_or_create_by_name :name => 'client_A02'
    eval_string = 'p company.clients'
    output_string = redirect { eval eval_string }
    second_size = output_string.size
    
    second_size.should == (first_size * 2)
    
    

    end end

    Hopefully this test case will help resolve the issue.

    March 15th, 2009 @ 02:13 AM

  2. David Medinets
    David Medinets

    Sorry about the bad formatting, let me try again.

    I have verified this behavior by creating a new application with a failing test case:

    
    script/generate rspec_model company name:string
    script/generate rspec_model client company_id:integer name:string
    

    Then I added the associations:

    
    class Company < ActiveRecord::Base
      has_many :clients
    end
    
    class Client < ActiveRecord::Base
      belongs_to :company
    end
    

    Here is a failing test case;

    
    require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
    require 'stringio'
    
    def redirect
      orig_defout = $stdout
      $stdout = StringIO.new
      yield
      $stdout.string
    ensure
      $stdout = orig_defout
    end
    
    describe Company do
      it "output size from company.clients should double after two clients are created" do
        company = Company.create! :name => 'AAA'
        company.clients.find_or_create_by_name :name => 'client_A01'
        eval_string = 'p company.clients'
        output_string = redirect { eval eval_string }
        first_size = output_string.size
        company.clients.find_or_create_by_name :name => 'client_A02'
        eval_string = 'p company.clients'
        output_string = redirect { eval eval_string }
        second_size = output_string.size
    
        second_size.should == (first_size * 2)
      end
    end
    

    March 15th, 2009 @ 02:27 AM

  3. Eloy Duran
    Eloy Duran

    Fixed your formatting a bit. After the 3 @'s you should specify the language that's used or nothing for plain code, but not a regular line of text :)

    March 16th, 2009 @ 09:33 AM

  4. David Medinets
    David Medinets

    After some additional experimentation, I learned that simply multiplying the string size was not correct. The updated spec test is below.

    Not sure if it helps but essentially the issue is that the non-working test does not call the create() method in association_collection.rb instead the create() method in base.rb is called. I am stepping through an execution trace (made by Unroller) to see if I can come up with a resolution.

    
    require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
    require 'stringio'
    
    def redirect
      orig_defout = $stdout
      $stdout = StringIO.new
      yield
      $stdout.string
    ensure
      $stdout = orig_defout
    end
    
    describe Company do
      it "output size from company.clients should double after two clients are created by create" do
        company = Company.create :name => 'AAA'
        company.clients.create :name => 'client_A01'
        company.clients.create :name => 'client_A02'
        eval_string = 'p company.clients'
        output_string = redirect { eval eval_string }
        output_string.size.should == 245
      end
    
      it "output size from company.clients should double after two clients are created by find_or_create" do
        company = Company.create :name => 'AAA'
        company.clients.find_or_create_by_name :name => 'client_A01'
        company.clients.find_or_create_by_name :name => 'client_A02'
        eval_string = 'p company.clients'
        output_string = redirect { eval eval_string }
        second_size = output_string.size
        second_size.should == 245
      end
    end
    

    March 16th, 2009 @ 09:56 AM

  5. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to incomplete
    • Assigned user set to Jeremy Kemper

    Pending a patch against master and test case.

    September 12th, 2009 @ 02:18 AM

  6. Jeremy Kemper
    Jeremy Kemper
    • Milestone changed from 2.x to 3.x

    May 4th, 2010 @ 06:48 PM

  7. Santiago Pastorino
    Santiago Pastorino
    • State changed from incomplete to open
    • Tag changed from 2.3-rc2, activerecord, association, association_proxy, edge, find_or_create to 23-rc2, activerecord, association, association_proxy, edge, find_or_create
    • Importance changed from to

    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.

    February 2nd, 2011 @ 04:53 PM

  8. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 04:53 PM