4

I have a complicated issue with Devise and the paranoia(acts_as_paranoid) gem. My User model is relatively simple:

class User < AR::Base
  devise :confirmable, :other_config_options
  acts_as_paranoid
end

I added the Devise gem first without the confirmable option. Then I later added the confirmable option with this migration:

def up
  add_column :users, :confirmed_at, :datetime
  add_column :users, :confirmation_token, :string
  add_column :users, :confirmation_sent_at, :datetime
  add_column :users, :unconfirmed_email, :string

  add_index :users, :confirmation_token, unique: true

  User.update_all(:confirmed_at => Time.now)
end

No problem up to this point. Then I added the Paranoia gem and the acts_as_paranoid line to the User model. My database is fine in its current state, but I'm trying to reset my database to sync it with production data, and this is where I'm running into problems. When I do a db:reset, it fails the above migration:

PG::UndefinedColumn: ERROR:  column users.deleted_at does not exist

The trouble is that my model contains a directive acts_as_paranoid that is valid only with the current database snapshot. If I roll back to a previous database snapshot, User::deleted_at doesn't exist, the paranoia gem still attempts to update only non-deleted objects, and my query fails.

Any thoughts on an elegant way to handle this situation?

kid_drew
  • 3,857
  • 6
  • 28
  • 38
  • 1
    Have you tried to create migration for missing columns? Paranoid gem ~ act_as_paranoid says that you need to run following migration: rails generate migration AddDeletedAtToClients deleted_at:datetime:index – Miknash Dec 03 '14 at 18:12
  • 1
    Yes, but that's done later in the migration path. This error is happening before that. I didn't have any problem installing paranoid - I only encountered this problem when I attempted to drop and rebuild my database from scratch. – kid_drew Dec 03 '14 at 19:41
  • I have this same issue. If I comment out acts_as_paranoid in my model it works but that is obviously just stopping whatever checking is going on in the model for if it is deleted. Interested in the proper solution to this. – Jordan Ell Dec 09 '14 at 22:49

3 Answers3

5

Use unscoped while using models + migration + acts_as_paranoid.

The line to update all users should be like this:

User.unscoped.update_all(:confirmed_at => Time.now)

Rael Gugelmin Cunha
  • 3,327
  • 30
  • 25
4

Not entirely sure if this is the most elegant solution, but I solved by updating my old migrations with User.with_deleted.update_all(:confirmed_at => Time.now) (well - my models' version).

May not work if you want users who have deleted_at set to not set confirmed_at; for me, I didn't really care if the deleted users had this field set (for me - this is only an issue in dev/test, and usually happens where there are no records in the first place).

After all this - I think it may be time for me to look at using seeds or a gem for DML migrations

p5k6
  • 56
  • 3
  • I suppose modifying previous migrations to reflect more recent code changes is a reasonable solution. I bet someone would disagree with me. – kid_drew Jun 10 '15 at 05:37
1

I was getting the error with existing migrations that were running an all and a each loop

So updated the code from:

Object.all.each do |obj|

To:

Object.with_deleted.each do |obj|

And that with_deleted.each solved the issue

Hope this helps!

d1jhoni1b
  • 7,497
  • 1
  • 51
  • 37