Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., @Microsoft, ex-@ShopifyEng, @OpenSearchProj, @awscloud, former CTO @artsy, +@vestris, NYC

Email Twitter LinkedIn Github Strava
Creative Commons License

Mongoid models provide an excellent level of abstraction. Consider a User model.

class User
  include Mongoid::Document

  devise :invitable, :database_authenticatable # ...

  field :name, type: String
  field :email, type: String
end

We have derived an _Admin _type from it.

class Admin < User
end

This avoids having to have an explicit user type. In the database the distinction will be the _type field and correct objects are instantiated by querying auto-magically.

But how do we promote a User into an Admin?

We have to change the internal _type field. So far I found only one way, reach down to MongoDB and update the field explicitly.

def self.promote!(user)
  users = Mongoid.master.collection('users')
  users.update({ _id: user.id }, { '$set': { _type: 'Admin' } })
end

I feel dirty. Is there a better way?