0

I'm adding a counter_cache, and my migrate is getting an error.

def up
    add_column :benefits, :benefit_rows_count, :integer, :default => 0

    Benefit.reset_column_information
    Benefit.find(:all).each do |b|
      Benefit.update_counters b.id, :benefit_rows_count => b.benefit_rows.length
    end
end

SQL:

UPDATE "benefits" SET "benefit_rows_count" = COALESCE("benefit_rows_count", 0) + 0 
WHERE "benefits"."id" IN (SELECT "benefits"."id" 
    FROM "benefits"
    WHERE "benefits"."id" = 1 
    ORDER BY benefit_types.position, benefit_types.name, id)

This ORDER BY, inside the update is because of the default_scope, and it fails the migration.

Unfortunately, when i update the record, i get the same error when the callback update_counters is executed. I've read some posts that said default_scope should be avoided. I checked Rails 4 source code (i'm using Rails 3) and update_counters has not been fixed. I'm going to reopen ActiveRecord::CounterCache.update_counters and try to unscope it.

4

2 回答 2

1

As already noted, your default scopes are tripping you up. There's a better way to avoid this sort of issue in your migrations: redefine your model in the scope of the migration:

class MigrateFooToBar < ActiveRecord::Migration

  class Foo < ActiveRecord::Base; end

  def up
    # ...
  end
end

When you then reference Foo from within up you reference the void-of-restrictions-and-default-scopes MigrateFooToBar::Foo which keeps you migrations from A) having to know too much about your models and B) confusing everybody else on your team when they run your migrations.

于 2013-07-05T19:47:43.293 回答
0

Thx Baldrick, i'm new to rails. And unscoped worked:

Benefit.unscoped.update_counters b.id, :benefit_rows_count => b.benefit_rows.length
于 2013-07-05T19:43:46.373 回答