Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a singleton global object in rails?

I have an object that I want created once and accessible in one of my models. Where do I put him? I'm afraid if I put him in the model class file he'll get created every time I make a new instance of that model. I only want this object created once at start up. Here's the object:

require 'pubnub'     publish_key   = 'fdasfs' subscribe_key = 'sdfsdsf' secret_key    = 'fsdfsd' ssl_on        = false  pubnub_obj = Pubnub.new(publish_key,                     subscribe_key,                     secret_key,                     ssl_on) 

I use him like this in the model:

class Message < ActiveRecord::Base    def self.send_new_message_client(message)     message = { 'some_data' => message }     info = pubnub_obj.publish({                             'channel' => 'testing',                             'message' => message                           })     puts(info)   end  end 
like image 858
stackOverlord Avatar asked May 25 '12 23:05

stackOverlord


People also ask

Are singletons global?

How is singleton different than global variable/class? The Singleton pattern is basically just a lazily initialized global variable. It ensures that the class has one instance and that instance is globally accessible. However, do not confuse Singleton design pattern with single instances.

What is the difference between global and singleton?

Singleton class ensures that not more than one object is created. However, having a global object doesn't ensure this. This class will not create more than one object.

Can we create object of singleton class?

It falls under the category of the creational design pattern in Java. A Singleton class in Java allows only one instance to be created and provides global access to all other classes through this single object or instance.

How many objects we can create in singleton?

In object-oriented programming, a singleton class is a class that can have only one object (an instance of the class) at a time.


2 Answers

In Rails, objects are recreated on each request. If this is some kind of service, it should be a singleton in the scope of a request.

Singleton objects should be created with the ruby singleton mixin:

require 'singleton'  class Pubnub   include Singleton    def initialize(publish_key, subscribe_key, secret_key, ssl_on)     # ...   end    def publish     # ...   end end 

Then you can call it with the instance method:

Pubnub.instance.publish 

This way you make sure that this object will actually be a singleton (only one instance will exist).

You can place it safely in the models directory, though I often prefer the lib directory or maybe create a new directory for services. It depends on the situation.

Hope it helps!

like image 59
alf Avatar answered Oct 09 '22 10:10

alf


If you want only one instance in your whole application, use a singleton, otherwise use a class variable.

To use a singleton, include the Singleton mixin.

require 'singleton'  class Pubnub   include Singleton    attr_writer :publish_key, :subscribe_key, :secret_key, :ssl_on    def publish     #...   end end 

and then use it like this:

require 'pubnub'     class Message < ActiveRecord::Base   Pubnub.instance.publish_key = 'xyz'   Pubnub.instance.subscribe_key = 'xyz'   Pubnub.instance.secret_key = 'xyz'   Pubnub.instance.ssl_on = 'xyz'    def self.send_new_message_client(message)     message = { 'some_data' => message }     info = Pubnub.instance.publish({                             'channel' => 'testing',                             'message' => message                           })     puts(info)   end end 

You could also make it a class variable, to link it more tightly to a specific model:

require 'pubnub'     class Message < ActiveRecord::Base     @@pubnub_obj = Pubnub.new('xyz', 'xyz', 'xyz', 'xyz')    def self.send_new_message_client(message)     message = { 'some_data' => message }     info = @@pubnub_obj.publish({                             'channel' => 'testing',                             'message' => message                           })     puts(info)   end  end 
like image 43
iHiD Avatar answered Oct 09 '22 10:10

iHiD