Block the creation of multiple class objects

How to limit an object of any class to one. My class is as follows:

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

I just want one copy of the speaker. One way is to add a check that checks the number of objects already present in the Speaker class. Is there a ruby ​​way to do something?

+7
source share
6 answers

How about using a Singleton module?

+10
source

In this case, I would write the correct check:

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

I recommend using a class / module that is designed to store configuration values, and not for your own use on top of the ActiveRecord model using vanilla.

I am using an old copy of the rails-settings plugin with some custom modification (it still works fine in Rails 3). Github also has a number of suggestion options, so feel free to watch and choose.

+3
source

Why not provide a default Speaker object and simply not provide controller actions to create or delete?

The simplest solution seems far.

+3
source

I see that you are using Mongoid

The requested function is not available using the mongoid check .

Therefore, you will need to write your own. before_validation is a supported callback and a chain of Speaker.all.count methods are available to your model .

 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 

However, best practice is to put all the key / value parameters in one table .

+3
source

Using the Singleton module and overriding its methods a bit, I believe this works, and it is thread safe (on 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 
+2
source

All Articles