Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

has_and_belongs_to_many defined in "migration's private model" kills migration #1973

Closed
olek opened this issue Jul 5, 2011 · 8 comments
Closed

Comments

@olek
Copy link

olek commented Jul 5, 2011

Some of us use migrations not just to manage schema, but to also manage basic data.
Hopefully, most are utilizing concept of private models defined inside of the migrations to avoid problems with app-model/migration compatibility in the future.

Well, during upgrade to 3.0 I found that if that 'private' models contains has_and_belongs_to_many relation to another private model, Rails attempts to load meta-data about that relation immediately upon reading model class description, but since at that time table does not yet exist (migration is just about to get executed), database (postgres 8.4) gets terribly upset, invalidates current transaction, and then Rails dies executing next (innocent) query that attempts creating the table, featuring not-so-helpful message "PGError: ERROR: current transaction is aborted, commands ignored until end of transaction block".

I have 2 issues with that.

First, when active record's internal query fails, it should manifest about that loudly, to make troubleshooting easier, instead of sweeping dirt under the rug and quietly moving on, hoping that nobody will notice.

Second, active record should not access database at that point (loading class definition) just yet. Older releases of Rails were not doing that (starting at 1.x, and then 2.0, 2.1, 2.2 and 2.3). Rails 3.0 handles 'belongs_to' and 'has_many' relations properly as well, it is only 'has_and_belongs_to_many' that causes trouble.

Example (can have mistakes since it is bastardized version of our production code):

class Foo < ActiveRecord::Migration
  class Channel < ActiveRecord::Base
    has_and_belongs_to_many :channel_categories
  end

  class ChannelCategory < ActiveRecord::Base
    has_and_belongs_to_many :channels
  end

  def self.up
    create_table :channels do |t|
      t.string :name, :null => false
    end

    create_table :channel_categories do |t|
      t.string :name, :null => false
    end

    create_table :channel_categories_channels, :id => false do |t|
      t.integer :channel_category_id, :null => false
      t.integer :channel_id, :null => false
    end
    # here would be some data manipulation code using private models
  end

  def self.down
    drop_table :channel_categories_channels
    drop_table :channel_categories
    drop_table :channels
  end
end

Error in the postgres log:

  PK and serial sequence (0.7ms)   SELECT attr.attname, seq.relname
FROM pg_class seq,
pg_attribute attr,
pg_depend dep,
pg_namespace name,
pg_constraint cons
WHERE seq.oid = dep.objid
AND seq.relkind = 'S'
AND attr.attrelid = dep.refobjid
AND attr.attnum = dep.refobjsubid
AND attr.attrelid = cons.conrelid
AND attr.attnum = cons.conkey[1]
AND cons.contype = 'p'
AND dep.refobjid = '"channel_categories_channels"'::regclass
PGError: ERROR:  relation "channel_categories_channels" does not exist

Problem was found in Rails (active record) 3.0.9

@jonleighton
Copy link
Member

Please try with a 3.1 RC and report back if you still have the problem.

@olek
Copy link
Author

olek commented Jul 6, 2011

Issue confirmed with 3.1.rc4.

Mind you, I had to fabricate a bit different test, since 3.1 has its own unique bizarre issue that prevents me from loading fixtures in migrations, and that is one of my very first migrations. Looks like this issue is easy to reproduce - simply add HABTM between any 2 models in migration (relation table should not exist, of course), run migrations, see the error.

@kalabiyau
Copy link
Contributor

Have this issue to, but in some other way.

Migration1: Model1 created
Migration 3 ... N
Migration N-1: Model2 created
in Model1 and Model2  added HABTM relation
Migration N: Creates relation table 

And i have

PGError: ERROR:  current transaction is aborted, commands ignored until end of transaction block

In migration log and "table model1_model2 not found" in PGSQL log

Maybe this is because of position of migration in migration chain ?

@isaacsanders
Copy link
Contributor

@olek Is this still an issue?

@olek
Copy link
Author

olek commented Apr 28, 2012

Re-tested today with 3.2.3 - looks like issue was fixed, migrations with HABTM work just fine.

@isaacsanders
Copy link
Contributor

Can you close the issue?

@carlosantoniodasilva
Copy link
Member

@olek thanks for reporting back, I'm closing the issue.

@carlosantoniodasilva
Copy link
Member

@isaacsanders done, thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants