James Thigpen
James Thigpen

Reputation: 869

Mongoid Unique Constraint on Composite Key

I'm trying to follow the advice in Mongoid 3 - Check for uniqueness of composite key to have a model with a unique constraint on 2 fields.

The id declaration is this:

field :_id, type: String, default: &method(:generate_id)

private

  def generate_id
    user.id.to_s + offering.id.to_s
  end

But if I do this, it has a conniption when I instantiate an object via new because it tries to generate the id before it has a user and offering and it (rightly) doesn't want to use the id of nil. I can pass in the user and offering as constructor parameters and everything is fine.

My question is, is this the right way of doing this? It feels dirty given all the obtuse wackyness I have to do just to get a unique constraint. The code isn't very intent revealing at all. Is there a better way?

Upvotes: 0

Views: 1078

Answers (1)

Benjamin Manns
Benjamin Manns

Reputation: 9148

With plain MongoDB you would create this index with JavaScript like so (assuming your collection name is registrations):

db.registrations.ensureIndex( { "user_id": 1, "offering_id": 1 }, { unique: true } )

To generate this index with Mongoid, add this to your model:

index({ user_id: 1, offering_id: 1 }, { unique: true })

And run rake db:mongoid:create_indexes.

If you want to keep generating your _id with generate_id, you could move the generation to a before_validate callback.

field :_id, type: String

before_validate :generate_id

private

def generate_id
  self._id ||= "#{user.id}:#{offering}"
end

Upvotes: 8

Related Questions