Associations are picking the wrong class

Hi guys,

Before opening a ticket, I want to be sure if this is a bug or not.
Example:

  class User < ActiveRecord::Base
  end

  class Admin::User < ActiveRecord::Base
  end

And then:

  class Account < ActiveRecord::Base
    belongs_to :user
  end

When I was calling Account.new.build_user, it was trying to create a
new Admin::User because the default class_name is just "User". To fix
the problem, I had to do:

  class Account < ActiveRecord::Base
    belongs_to :user, :class_name => '::User'
  end

It also has problems in the opposite way:

  class User < ActiveRecord::Base
  end

  class Admin::User < ActiveRecord::Base
  end

And then:

  class Admin::Account < ActiveRecord::Base
    belongs_to :user
  end

Sometimes Admin::Account.build_user is trying to build a ::User and
other times ::Admin::User, because, again the default class_name is
just "User".

My opinion is that in the first case, the class name should be by
default "::User" and in the second it should be "::Admin::User".

The thing is, since the patch comes in, it will break apps that are
relying in this wrong behavior. The good point is that the error will
be raised when the application starts. The way it's now, takes quite
sometime for you to discover that Account was trying to build a
Admin::User instead of User.

Are you in or out for this change?

Regards,

José Valim.

I would say leave it alone for now. It does seem weird that it chooses the non-obvious one each time, but some of the big wigs have voiced opinions against the idea of namespacing models in general. And their arguments make sense.

http://m.onkey.org/2007/12/9/namespaced-models
http://stackoverflow.com/questions/601768?sort=oldest
http://www.strictlyuntyped.com/2008/08/activerecord-can-haz-namespaces.html

Really? Despite namespace models have an issue, wouldn’t this just be bad in general for all sorts of other reason? What if the model it chose was in a namespace for a plugin or something else vendor related?

It just seems to me that despite weather namespacing a models are present the assumed constant for the declaration would do what is expected. Is the fix crazy or simple?

  • Ken

http://m.onkey.org/2007/12/9/namespaced-models

This one begins with a comment of “I don’t really understand why people use namespaced models.” That’s not really a compelling argument.

There is a reason we namespace things in general. Otherwise, why have these top-level modules like ActiveRecord in the first place?

http://stackoverflow.com/questions/601768?sort=oldest

The main argument here, other than the strictlyuntyped link, is that you can’t do it in the database – so what? You can’t define methods on a database table either, yet we do it in Rails. Database tables can’t be polymorphic all by themselves, but Rails adds that. And the naming convention could ensure that while it is a flat namespace of DB tables, the namespaced ones will never conflict with anything outside that namespace.

http://www.strictlyuntyped.com/2008/08/activerecord-can-haz-namespaces.html

This describes bugs in the current implementation.

So, it looks like the biggest argument not to use namespaced models is that they don’t work very well in Rails.

Really?

Isn’t that a bit like arguing we shouldn’t have started using REST, because it didn’t work very well in Rails? That was seen as a bug to be fixed, or a feature to be added, not a hazard to be avoided.

The other argument that seems to be tossed around a lot is that you can put things into a subfolder. Somehow, I think that would be less useful – now the convention of filename->class name is broken, and I can’t get a list of all top-level model classes by looking in app/models. It also doesn’t address the real reasons you might use namespaces.

If anyone can offer any reason namespaces shouldn’t be done, other than that Rails doesn’t do them well, that’d be a more interesting discussion.

Otherwise, it’s circular reasoning. We shouldn’t fix Rails namespacing, because namespacing is a bad idea, because Rails doesn’t do namespacing well, because no one’s fixed it yet.

Really? Despite namespace models have an issue, wouldn't this just be
bad in general for all sorts of other reason? What if the model it
chose was in a namespace for a plugin or something else vendor related?

This is exactly what happened. I'm not using namespaces in my
application but I've installed Typus (http://github.com/fesplugas/
typus) as plugin and since it has Typus::User, my application (Rails
2.3.2) started to pick up Typus::User instead of User when doing
Account.build_user.

Is the fix crazy or simple?

The fix is simple: 3 files changed, 12 insertions(+), 3 deletions(-).

http://m.onkey.org/2007/12/9/namespaced-models
http://stackoverflow.com/questions/601768?sort=oldest
http://www.strictlyuntyped.com/2008/08/activerecord-can-haz-namespace

Ryan Angilly, those posts say: "don't use namespaced models". But as
Ken pointed out, your plugins, gems, etc can use.
If you listening their advice and not using namespaced models, the fix
won't affect you.

Created a patched.

http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2262-associations-are-picking-the-wrong-class

Yeah, I get what you’re saying. I thought it would be a much bigger deal to change it.