This project is archived and is in readonly mode.
has_one with :foreign_key & :primary_key bug
-
Brian Johnson
I just ran into this same bug and this patch is incomplete. I will generate work on a test case and patch.
-
Brian Johnson
ok, should be
associations.rb
@@@ def has_one(association_id, options = {})
if options[:through] reflection = create_has_one_through_reflection(association_id, options) association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation) else reflection = create_has_one_reflection(association_id, options) ivar = "@#{reflection.name}" method_name = "has_one_after_save_for_#{reflection.name}".to_sym define_method(method_name) do association = instance_variable_get(ivar) if instance_variable_defined?(ivar) primary_key = reflection.options[:primary_key] || :id if !association.nil? && (new_record? || association.new_record? || association[reflection.primary_key_name] != send(primary_key)) association[reflection.primary_key_name] = send(primary_key) association.save(true) end end after_save method_name add_single_associated_validation_callbacks(reflection.name) if options[:validate] == true association_accessor_methods(reflection, ActiveRecord::Associations::HasOneAssociation) association_constructor_method(:build, reflection, ActiveRecord::Associations::HasOneAssociation) association_constructor_method(:create, reflection, ActiveRecord::Associations::HasOneAssociation) configure_dependency_for_has_one(reflection) end endhas_one_association.rb @@@ def new_record(replace_existing) # Make sure we load the target first, if we plan on replacing the existing # instance. Otherwise, if the target has not previously been loaded # elsewhere, the instance we create will get orphaned. load_target if replace_existing record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do yield @reflection end if replace_existing replace(record, true) else puts "test" record[@reflection.primary_key_name] = @reflection.options.has_key?(:primary_key) ? @owner.send(@reflection.options[:primary_key]) : @owner.id unless @owner.new_record? self.target = record end record endassociation_proxy.rb
@@@ def set_belongs_to_association_for(record)
if @reflection.options[:as] record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record? record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s else record[@reflection.primary_key_name] = @reflection.options.has_key?(:primary_key) ? @owner.send(@reflection.options[:primary_key]) : @owner.id unless @owner.new_record? end endSorry I don't have a real patch, it's late and I'm tired. -
Brian Johnson
Ok, here is the fix including tests from graeme
-
Thomas Shelton
I'm a complete noob here so forgive me if I missed something. I believe there is still a bug with respect to this fix. Although the association works when referenced directly from an object, when the associations are loaded through an :include, they still reference the original primary key.
I changed association_preload.rb as described in the attached diff.
Is this something that can be added to the proposed fix or should I do something further?
Thanks, Thomas
-
Brian Johnson
If you can make a test case for it I will add it to my git repo. Not sure what the best way to get this back into the main repo though, maybe I should do a pull request?
-
Brian Johnson
just FYI - looks like this is already changed in edge, but the association isn't preloading for me. I'm working on a test case for it.
id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key])
-
Brian Johnson
apparently my issue was related to http://rails.lighthouseapp.com/p...
-
Brian Johnson
Ok, everything is good on edge rails with include, but I added a test case to the git repo anyway.
-
gbp
For the record: original problem still exists. The tests in my patch still fail on edge rails.
-
Brian Johnson
That's really strange because id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key]) is functionally equivalent to your patch. You didn't include the failing test, can you provide it?
-
gbp
My problem resides in associations.rb (currently Line 906) - not association_preload.rb. On edge rails the test provided in my original patch do fail without the patch to associations.rb being applied.
-
Brian Johnson
Graeme, your tests pass on my fork. Thomas, I'd like to include your issue as well, but I need a failing test first.
-
gbp
Updated patch for rails 2.3.2
-
Eloy Duran
- Assigned user set to Eloy Duran
-
Eloy Duran
- State changed from new to verified
I have verified and applied this patch on my branch of 2-3-stable, which Micheal will look at and merge in before 2.3.4.
http://github.com/alloy/rails/commit/e5de99082a7d151a70e8d48b96471f...
Thanks!
-
Repository
- State changed from verified to resolved
(from [a070873771ebede9097735f07fc40720dce89c46]) Fix has_one with foreign_key and primary_key association bug which caused the associated object being lost when saving the owner. [#1756 has_one with :foreign_key & :primary_key bug state:resolved]
Mixed in a bit from patch by ransom-briggs. [#2813 autosave for has_one does not work properly with primary_key option state:resolved]
Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
http://github.com/rails/rails/commit/a070873771ebede9097735f07fc407... -
Repository
(from [c01be9de322ba846923340e41e69821d01541610]) Fix has_one with foreign_key and primary_key association bug which caused the associated object being lost when saving the owner. [#1756 has_one with :foreign_key & :primary_key bug state:resolved]
Mixed in a bit from patch by ransom-briggs. [#2813 autosave for has_one does not work properly with primary_key option state:resolved]
Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
http://github.com/rails/rails/commit/c01be9de322ba846923340e41e6982... -
tribalvibes
- Tag changed from activerecord, foreign_key, patch, primary_key to 2.3.10, 2.3.8, activerecord, foreign_key, has_many, patch, primary_key
- Importance changed from to High
Similar to #1633 has_many with :primary_key option bug which is still a bug in 2.3.8
has_many association.create doesn't set the new record fk correctly when the association pk is designated with :primary_key -
Andrea Campi
- Tag changed from 2.3.10, 2.3.8, activerecord, foreign_key, has_many, patch, primary_key to 2-3-stable, activerecord, foreign_key, has_many, patch, primary_key
