Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

has and belongs to many join tables do not allow primary keys #534

Closed
omarqureshi opened this Issue · 6 comments

4 participants

@omarqureshi

Assuming a join table of the following structure:

    create table articles_tags(
      article_id            integer not null references articles(id),
      tag_id                integer not null references tags(id),
      primary key(article_id, tag_id)
    );

Running db:seed gives me the following error:

Primary key is not allowed in a has_and_belongs_to_many join table (articles_tags).
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/associations/builder/has_and_belongs_to_many.rb:44:in `check_validity'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/associations/builder/has_and_belongs_to_many.rb:9:in `build'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/associations/builder/collection_association.rb:13:in `build'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/associations.rb:1573:in `has_and_belongs_to_many'
/Users/omarqureshi/Source/Blog/app/models/article.rb:4:in `<class:Article>'
/Users/omarqureshi/Source/Blog/app/models/article.rb:1:in `<top (required)>'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:452:in `load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:452:in `block in load_file'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:639:in `new_constants_in'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:451:in `load_file'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:338:in `require_or_load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:489:in `load_missing_constant'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:181:in `block in const_missing'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:179:in `each'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:179:in `const_missing'
/Users/omarqureshi/Source/Blog/db/seeds.rb:11:in `block in <top (required)>'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/connection_adapters/abstract/database_statements.rb:191:in `transaction'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/transactions.rb:208:in `transaction'
/Users/omarqureshi/Source/Blog/db/seeds.rb:1:in `<top (required)>'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:233:in `load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:233:in `block in load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:223:in `block in load_dependency'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:639:in `new_constants_in'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:223:in `load_dependency'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:233:in `load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/railties-3.1.0.beta1/lib/rails/engine.rb:470:in `load_seed'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@omarblog/gems/activerecord-3.1.0.beta1/lib/active_record/railties/databases.rake:295:in `block (2 levels) in <top (required)>'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:636:in `block in execute'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:597:in `block in invoke_with_call_chain'
/Users/omarqureshi/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2029:in `block (2 levels) in top_level'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2029:in `each'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2029:in `block in top_level'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2001:in `block in run'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/gems/rake-0.8.7/bin/rake:31:in `<top (required)>'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/bin/rake:19:in `load'
/Users/omarqureshi/.rvm/gems/ruby-1.9.2-p180@global/bin/rake:19:in `<main>'

Why does activerecord now care about whether join tables have primary keys?

@jonleighton
Collaborator

Myself and @tenderlove both think that we should not care about primary keys on the join table, but we're not sure why this error was added in the first place.

@lifo can you shed any light?

@jonleighton
Collaborator

I did a bit of digging through the commit log. Here's when the error was first introduced: 9d51f62

Here's the lighthouse ticket: https://rails.lighthouseapp.com/projects/8994/tickets/2086

There used to be a feature whereby extra fields on a habtm join table would appear on the associated model. And so the concern was that by allowing a user to define "id" on their join table (for example), that could overwrite the id field on the associated record's object and cause confusing problems.

However, the above feature has been deprecated for a long time and is being removed in 3.1. So I think we can now remove this error message too. I'm going to set the milestone as 3.2 though as the focus at the moment is on fixing regressions.

@omarqureshi

That is interesting, i'm pretty sure I haven't been bit by this in 2.3 / 3.0.
Thanks though

@omarqureshi omarqureshi reopened this
@dmathieu
Collaborator

This has been solved with the previously displayed commit. The issue should be closed.

cc @jonleighton

@cheerfulstoic

Couldn't this be ported to the 3.1.x line? I'm converting a large application to 3.1 and it has many, many join tables with primary keys on the two columns. It seems like a regression in functionality to me

@dmathieu
Collaborator

I've done it in #3036, waiting to be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.