I came across an interesting issue this morning using Rails 3 beta 4.
in my user.rb I have a scope:
scope :public, where(:private => false)
This was absolutely fine when I added the scope, since the "private"
field was in the database.
I wanted to modify the migration, so I rolled back the database, but
by doing so, I nuked the private field.
Now when I try to rollback or run any migrations, I get:
No attribute named `private` exists for table `users`
This is happening (I think) because Rails is building the predicate
for the scope at runtime ... when the field doesn't exist.
Whenever something like this happened in Rails 2, I'd normally put the
class inside the migration, eg:
class AddUsernameToUser < ActiveRecord::Migration
class User < ActiveRecord::Base
add_column :users, :username, :string
add_column :users, :private, :boolean, :default => false
remove_column :users, :private
remove_column :users, :username
This doesn't work in this case, because it all happens before _any_
migration is run.
So basically, I have to remove the scope to run any migrations.
This is fine for now, as I can move on with development, but the
implication is that if I start off with a clean database, and run rake
db:migrate, it won't work.
Now, I know that best practice is to use rake db:schema:load, but I
think that this is still a brittle case.
Basically, by adding a scope that depends on a field existing, all
prior migrations break.