Validating embedded document in Mongoid based on e

2019-07-07 17:07发布

I've a class Subscriber which has embeds_many Subscriptions. Subscription has an attribute status. I want to add a validation on status such that only one Subscription can have status 'active' per subscriber. The subscriber can have multiple subscription with status 'purchased' or 'expired' .

标签: mongoid
1条回答
不美不萌又怎样
2楼-- · 2019-07-07 17:50

This should do it:

class Subscriber
  include Mongoid::Document
  embeds_many :subscriptions
  validate :active_subscriptions

  def active_subscriptions
    self.errors.add(:base, 'too many active subscriptions') if 
        subscriptions.where(status: 'active').count > 1
  end
end

class Subscription
  include Mongoid::Document
  embedded_in :subscriber
  field :status, class: 'String'
end

s = Subscriber.create
s.subscriptions.build(status: 'active')
s.save # fires validations on subscriber
s.subscriptions.build(status: 'active')
s.save # wouldn't save

But make sure that you always call save on subscriber, otherwise the validations will not fire on subscriber and you will land in an inconsistent state. In an inconsistent state you might see failing validations later

s = Subscriber.create
s.subscriptions.create(status: 'active') # fires validations on subscription only
s.subscriptions.build(status: 'active').save # fires validations on subscription only

If you need to also validate subscription, when saving subscriber, you cascade callbacks:

embeds_many :subscriptions, cascade_callbacks: true
查看更多
登录 后发表回答