This project is archived and is in readonly mode.
AR#find_or_create doesn't add the created model to collection
Reported by Akira Matsuda | March 11th, 2009 @ 11:40 AM | in 3.x
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?
Comments and changes to this ticket
-
David Medinets March 15th, 2009 @ 02:13 AM
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.
-
David Medinets March 15th, 2009 @ 02:27 AM
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
-
Eloy Duran March 16th, 2009 @ 09:33 AM
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 :)
-
David Medinets March 16th, 2009 @ 09:56 AM
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
-
Jeremy Kemper September 12th, 2009 @ 02:18 AM
- State changed from new to incomplete
- Assigned user set to Jeremy Kemper
Pending a patch against master and test case.
-
Santiago Pastorino February 2nd, 2011 @ 04:53 PM
- 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.
-
Santiago Pastorino February 2nd, 2011 @ 04:53 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>