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.

carlosvini
  • 1,742
  • 19
  • 18
  • 1
    What did you put in your migration file ? you can ignore the default scope with `unscoped` in Rails 3: http://stackoverflow.com/a/4166950/1128103 – Baldrick Jul 05 '13 at 18:32

2 Answers2

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.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • For now, i won't use default_scope. This project was started by other programmer, but i took the liberty to change default_scopes for named scopes. – carlosvini Jul 12 '13 at 18:48
0

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

Benefit.unscoped.update_counters b.id, :benefit_rows_count => b.benefit_rows.length
carlosvini
  • 1,742
  • 19
  • 18