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.

Model Namespaces and HABTM

#4975

If you have a model under a namespace and try to set up any HABTM association with it, the join table that it tries to use by default strips out the namespace. Given all the rails 3 work to improve handling of namespaces controllers, helpers and models, I don't think this functionality is intended anymore.

Sample construction of namespaced models with HABTM:

class Contact < ActiveRecord::Base
  has_and_belongs_to_many :organizations
end

class Contact::Address < ActiveRecord::Base
  has_and_belongs_to_many :organizations
end

class Contact::Organization < ActiveRecord::Base
  has_and_belongs_to_many :addresses
  has_and_belongs_to_many :contacts
end

create_table :contacts
create_table :contact_addresses
create_table :contact_addresses_contact_organizations, :id => false do |t|
  t.references :address; t.references :organization
end
create_table :contact_organizations
create_table :contacts_contact_organizations, :id => false do |t|
  t.references :contact; t.references :organization
end

Because of a call to demodulize inside undecorated_table_name, the namespaces are stripped away and is the only reason the above does not work. Manually specifying :join_table shows perfect functionality.

irb(main):001:0> c = Contact.create
=> #<Contact id: 1>
irb(main):002:0> org = c.organizations.create
=> #<Contact::Organization id: 1>
irb(main):003:0> a = org.addresses.create
=> #<Contact::Address id: 1>
irb(main):004:0> c2 = Contact.create
=> #<Contact id: 2>
irb(main):005:0> c2.organizations << org
=> [#<Contact::Organization id: 1>]
irb(main):006:0> org2 = Contact::Organization.create
=> #<Contact::Organization id: 2>
irb(main):007:0> org2.addresses << a
=> [#<Contact::Address id: 1>]
irb(main):008:0> c2.organizations << org2
=> [#<Contact::Organization id: 1>, #<Contact::Organization id: 2>]

First thoughts for a solution is to rewrite join_table_name in activerecord/lib/active_record/associations.rb to do the same as undecorated_table_name sans the demodulize.

Reported by Samuel Kadolph · June 25th, 2010 @ 09:48 PM

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

Activity

  1. Kane
    Kane

    table_name

    Nested classes are given table names prefixed by the singular form of the parent‘s table name. Enclosing modules are not considered.

    i think the underlying problem is that create_has_and_belongs_to_many_reflection which is the only method that uses join_table_name does not use the classes table names but constructs them differently.
    so neither nested classes, overridden table names nor table suffixes or prefixes are respected.

    if someone from the core team could give me green light, i would write a patch with regression tests for this issue.

    June 27th, 2010 @ 01:31 AM

  2. Kane
    Kane

    addition:

    @Samuel Kadolph

    to clarify some things: this is not directly a bug. the current behaviour is as described:

    has_and_belongs_to_many

    Specifies a many-to-many relationship with another class. This associates two classes via an intermediate join table. Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names.

    the question is, should it really be that way?
    Personally i would say it shoudnt use the class names bit the table names.
    Im aware that a change of this would break existing apps, so this definitely needs discussion.

    June 27th, 2010 @ 01:38 AM

  3. Samuel Kadolph
    Samuel Kadolph

    That's why I never used the word bug.
    However with all of the changes to allow for namespacing of controllers, helpers and models. It only makes sense that all AR associations work as one would expect under a namespace.

    June 27th, 2010 @ 01:40 AM

  4. Kane
    Kane

    you dont namespace, what you described are nested classes. If you would use namespacing the namespace wouldnt go into the table name and everything would be okey.

    June 27th, 2010 @ 01:46 AM

  5. Samuel Kadolph
    Samuel Kadolph

    The same thing happens when they are under a module named Contact. Which isn't what you would want, anything under the Contact namespace (class or module) should always have the prefix contact_ regardless of the association or the individual's AR table_prefix.

    June 27th, 2010 @ 01:51 AM

  6. Andrea Campi
    Andrea Campi

    Can you provide a patch with tests? This proposal sounds interesting.

    October 17th, 2010 @ 02:21 PM

  7. Santiago Pastorino
    Santiago Pastorino
    • State changed from new to open

    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.

    February 2nd, 2011 @ 04:28 PM

  8. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 04:28 PM

  9. bingbing