Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 374
Dan Sowter Avatar asked May 23 '12 23:05

Dan Sowter


2 Answers

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.

like image 143
Nicholas Pufal Avatar answered Oct 05 '22 12:10

Nicholas Pufal


If your scopes begin with find_ like find_by_foo then they will break rake db:migrate. That was the bug in my case.

like image 24
Omar Ali Avatar answered Oct 05 '22 11:10

Omar Ali