This project is archived and is in readonly mode.

#4975 ✓stale
Samuel Kadolph

Model Namespaces and HABTM

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

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.

Comments and changes to this ticket

  • Kane

    Kane June 27th, 2010 @ 01:31 AM

    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.

  • Kane

    Kane June 27th, 2010 @ 01:38 AM

    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.

  • Samuel Kadolph

    Samuel Kadolph June 27th, 2010 @ 01:40 AM

    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.

  • Kane

    Kane June 27th, 2010 @ 01:46 AM

    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.

  • Samuel Kadolph

    Samuel Kadolph June 27th, 2010 @ 01:51 AM

    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.

  • Andrea Campi

    Andrea Campi October 17th, 2010 @ 02:21 PM

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

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:28 PM

    • 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.

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:28 PM

    • State changed from “open” to “stale”
  • bingbing

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>

Referenced by

Pages