This project is archived and is in readonly mode.

#269 ✓stale
Brian Cardarella

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

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

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.

Comments and changes to this ticket

  • Brian Cardarella

    Brian Cardarella May 28th, 2008 @ 06:22 PM

    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.

  • Brian Cardarella

    Brian Cardarella May 28th, 2008 @ 09:34 PM

    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.

  • Jeremy Kemper

    Jeremy Kemper May 31st, 2008 @ 09:29 PM

    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
    
  • Brian Cardarella

    Brian Cardarella May 31st, 2008 @ 09:33 PM

    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.

  • Jeremy Kemper

    Jeremy Kemper June 1st, 2008 @ 12:21 AM

    Why not? The behavior is consistent either way.

  • Brian Cardarella

    Brian Cardarella June 1st, 2008 @ 01:14 AM

    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.

  • josh

    josh July 17th, 2008 @ 02:06 AM

    • State changed from “new” to “stale”
    • Tag cleared.

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>

People watching this ticket

Pages