Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7395 (new defect)

Opened 1 year ago

Last modified 1 year ago

[PATCH] collection_singular_ids= should properly infer association class

Reported by: rounder Assigned to: bitsweat
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords: has_and_belongs_to_many collection_singular_ids=
Cc: me@julik.nl

Description

When we have two classes (SubModule::Car and SubModule::Tire) associated with have_and_belongs_to_many association and if car is an object of type SubModule::Car

car.tire_ids = ...

assumes that the association is with class Tire instead with class SubModule::Tire contrary to car.tires which knows that the class is SubModule::Tire. So you have to use :class_name with you association even if you use the defaults.

Attachments

do_not_infer_klass_7395.diff (2.3 kB) - added by julik on 01/28/07 09:22:17.

Change History

01/28/07 09:22:17 changed by julik

  • attachment do_not_infer_klass_7395.diff added.

01/28/07 18:04:49 changed by julik

  • cc set to me@julik.nl.
  • severity changed from minor to normal.
  • summary changed from collection_singular_ids= method created by has_and_belongs_to_many does not apply the module of the model class to [PATCH[ collection_singular_ids= should properly infer association class.

Test case and fix attached. Lookup via class_name in this case leads to a Ruby warning, so doing an extra lookup is not needed. In general it's a better idea to reflect on klass, not on class_name methinks

01/28/07 18:05:02 changed by julik

  • summary changed from [PATCH[ collection_singular_ids= should properly infer association class to [PATCH] collection_singular_ids= should properly infer association class.

01/28/07 18:28:47 changed by bitsweat

  • owner changed from core to bitsweat.

From the patch

Due to a subtle inconsistency in Ruby it cannot return a modulized (qualified) class name

Could you describe it?

01/28/07 18:51:14 changed by julik

If you put class_name.modulize.constantize in the class_name you will get multiple warnings even in the tests suite (that Developer in the namespace references top-level constant).

01/28/07 19:58:05 changed by julik

Ok, I'll try to explain. The bug described here occurs, because the original reflection code was doing a lookup via Reflection#class_name.constantize. What was forgotten is that it was effectively being called from _outside_ of the namespace native to the model class - therefore ::Developer comes _first_ instead of ::A::B::C::Developer.

So my first guess was that reflection association should return a qualified class_name (so that it can be reverse-mapped). However, when I did it, I started getting weird warnings in tests because somehow the inner Developer constant became referenced to ::Developer. Shortly speaking - mayhem.

And having another const_get in there was not DRY (because you already have Reflection#klass)