Model scopes are breaking rake db:migrate - rails 3.2.3 postgres 9.1.3

postgresql, ruby, ruby-on-rails, ruby-on-rails-3.2

Solution

I was having exactly the same problem. After 2 hours debugging and pulling my hair off, this blessed human being called Carl Zulauf posted the answer in the comments.

The problem is that the scopes are being evaluated when we run the migrations, so any dependency with another table that is not yet migrated will result in that error.

Just wrap all of your scopes with lambda. For instance:

scope :team_leaders, lambda { where(role_id: Role.where(name: 'Team Leader').first.try(:id)) }

Do that for all the scopes.

That should do the trick. They need to be lazy evaluated (just when get called), and without `lambda` they are being evaluated right away.

Problem

I've come across a problem with running my migrations in a new rails app (3.2.3). We're using postrgres 9.1.3 and - pg (0.13.2) - When I run rake db:create, then rake db:migrate, I get -> ``` 1.9.3-p194 (master) rake db:migrate --trace ** Invoke db:migrate (first_time) ** Invoke environment (first_time) ** Execute environment rake aborted! PG::Error: ERROR: relation "roles" does not exist LINE 4: WHERE a.attrelid = '"roles"'::regclass ^ : SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull FROM pg_attribute a LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum WHERE a.attrelid = '"roles"'::regclass AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum ``` I get this even without any migrations defined, so I don't believe it's a problem with the migrations themselves. When I look at the stack trace, I see that scopes defined in my User model are being run - when I comment them out, the migrations run without a problem. ``` scope :team_leaders, where(role_id: Role.where(name: 'Team Leader').first.try(:id)) scope :area_leaders, where(role_id: Role.where(name: 'Area Leader').first.try(:id)) scope :nation_leaders, where(role_id: Role.where(name: 'Nation Leader').first.try(:id)) scope :employees, where(role_id: Role.where(name: 'Employee').first.try(:id)) ``` Is this a bug in rails, or am I doing something wrong? I'd really appreciate some help - we can remove the use of these scopes across the app, but this is something we'd like to avoid. Should I be putting these scopes inside some sort of conditional which is called when rails is loaded in the console or as a server but not during migrations? Thanks very much, Dan Sowter

Original source