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.

has_many :class will nest within parent class... no override

#269

If I have two nested models:

User::Candidate

Resource::Resume

and I have within my candidate model:

has_many :resumes, :class => "Resource::Resume"

ActiveRecord will nest this class as:

User::Resource::Resume

At the very least there should be a class_prefix override available. Although I think if you are designating the class specifically there should be no prefix attached whatsoever.

I traced the issue to:

...../activerecord-2.0.2/lib/active_record/base.rb:1347:

def type_name_with_module(type_name)

(/^::/ =~ type_name) ? type_name : "#{parent.name}::#{type_name}"

end

I'll try to work on a patch and upload later.

Reported by Brian Cardarella · May 28th, 2008 @ 05:52 PM

State: stale
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Brian Cardarella
    Brian Cardarella

    A simple workaround to fix this:

    ..../activerecord-2.0.2/lib/active_record/reflection.rb:124

    def klass

    @klass ||= active_record.send(:compute_type, class_name)

    end

    change to:

    def klass

    @klass ||= options[:class_name].constantize || active_record.send(:compute_type, class_name)

    end

    If you dig into the class_name method it does check the options[:class_name] again so maybe this should be removed. But this will use whatever class you specify in a has_many without nesting it into the parent class of the current model.

    May 28th, 2008 @ 06:22 PM

  2. Brian Cardarella
    Brian Cardarella

    Small correction:

    def klass

    @klass ||= (options[:class_name].constantize rescue nil) || active_record.send(:compute_type, class_name)

    end

    Make this change to catch if options[:class_name] is nil or not a constant.

    Again, this is not the most elegant way but it seems to work.

    May 28th, 2008 @ 09:34 PM

  3. Jeremy Kemper
    Jeremy Kemper

    This is so the association can reference a sibling class without needing an explicit :class_name

    module UserStuff
      class User < ActiveRecord::Base
        has_many :resumes
      end
    
      class Resume < ActiveRecord::Base
      end
    end
    

    May 31st, 2008 @ 09:29 PM

  4. Brian Cardarella
    Brian Cardarella

    Jeremy,

    I understand this but when you explicitly define a class_name it will still treat the association as a sibling class instead of referencing the user defined class_name. ActiveRecord should not assume that a user defined class_name is a sibling class.

    May 31st, 2008 @ 09:33 PM

  5. Jeremy Kemper
    Jeremy Kemper

    Why not? The behavior is consistent either way.

    June 1st, 2008 @ 12:21 AM

  6. Brian Cardarella
    Brian Cardarella

    Because sometimes a child model may not be a sibling of a parent model. My original post:

     class Resource::Resume < ActiveRecord::Base; end
    
     class User::Candidate < ActiveRecord::Base
       has_many :resumes, :class_name => "Resource::Resume"
     end
    

    This will raise warnings. Note that I am using nested models. The User::Candidate model will refer to the :resumes association with User::Resource::Resume even after I specify the exactly class name. The proper class name is Resource::Resume.

    Again, if I am explicitly specifying the class name why does AR need to do any work guessing any additional parent classes? That should only be necessary when I do not explicitly specify a class name.

    June 1st, 2008 @ 01:14 AM

  7. josh
    josh
    • State changed from new to stale
    • Tag cleared.

    July 17th, 2008 @ 02:06 AM