阻止创建一个类的多个对象

时间:2011-08-19 11:25:31

标签: ruby-on-rails ruby ruby-on-rails-3 mongoid

如何将任何类的对象限制为一个。我的班级看起来像:

class Speaker
  include Mongoid::Document
  field :name, :type => String
end

我只想让一个扬声器的实例。一种方法是添加验证,该验证将检查已经存在的Speaker类的对象的数量。 有没有红宝石做事的方式?

6 个答案:

答案 0 :(得分:10)

如何使用Singleton模块?

答案 1 :(得分:8)

在这种情况下,我会写出适当的验证:

validate :only_one

def only_one
   errors.add(:base, "Only one Speaker can exist") if self.count > 0 
end

答案 2 :(得分:3)

我建议使用专门用于存储配置值的类/模块,而不是在vanilla ActiveRecord模型之上滚动自己。

我使用rails-settings插件的旧副本进行了一些自定义修改(它在Rails 3中仍能正常工作)。 Github上还列出了许多变体产品,所以请随意查看并选择。

答案 3 :(得分:3)

为什么不提供默认的Speaker对象,而不是为创建或删除提供控制器操作?

到目前为止似乎是最简单的解决方案。

答案 4 :(得分:3)

我看到你正在使用Mongoid

使用mongoid validations无法使用您请求的功能。

因此,您需要自己编写。 before_validationsupported callbackSpeaker.all.count方法are available to your model。{/ p>

class Speaker
  include Mongoid::Document
  field :name, :type => String
  before_validation(:ensure_has_only_one_record, :on => :create)
  def ensure_has_only_one_record
    self.errors.add :base, "There can only be one Speaker." if Speaker.all.count > 0
  end
end

然而,best practice is to put all key/value settings in a single table

答案 5 :(得分:2)

使用Singleton模块并略微重写其方法,我相信这是有效的,并且它是线程安全的(在ruby 1.8上):

class Speaker 

  include Singleton
  include Mongoid::Document
  field :name, :type => String

  @@singleton__instance__ = nil
  @@singleton__mutex__ = Mutex.new

  def self.instance
    return @@singleton__instance__ if @@singleton__instance__
    @@singleton__mutex__.synchronize {
      return @@singleton__instance__ if @@singleton__instance__
      @@singleton__instance__ = self.first
      @@singleton__instance__ ||= new()
    }
    @@singleton__instance__
  end

  def destroy
    @@singleton__mutex__.synchronize {
      super
      @@singleton__instance__ = nil
    }
  end

end
相关问题