Подтвердить что ты не робот

Как создать одноэлементный глобальный объект в рельсах

У меня есть объект, который я хочу создать один раз и доступен в одной из моих моделей. Где я его положил? Боюсь, если я поместил его в файл класса модели, он будет создан каждый раз, когда я создам новый экземпляр этой модели. Я только хочу, чтобы этот объект был создан один раз при запуске. Здесь объект:

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)

Я использую его вот так в модели:

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
4b9b3361

Ответ 1

В Rails объекты воссоздаются по каждому запросу. Если это какая-то услуга, она должна быть одиночной в рамках запроса.

Объекты Singleton должны быть созданы с помощью однослойного mixin ruby:

require 'singleton'

class Pubnub
  include Singleton

  def initialize(publish_key, subscribe_key, secret_key, ssl_on)
    # ...
  end

  def publish
    # ...
  end
end

Затем вы можете вызвать его с помощью метода instance:

Pubnub.instance.publish

Таким образом вы убедитесь, что этот объект будет на самом деле одиночным (только один экземпляр будет существовать).

Вы можете безопасно разместить его в каталоге models, хотя я часто предпочитаю каталог lib или, возможно, создаю новый каталог для служб. Это зависит от ситуации.

Надеюсь, что это поможет!

Ответ 2

Если вам нужен только один экземпляр во всем приложении, используйте одноэлемент, иначе используйте переменную класса.

Чтобы использовать один синглтон, включите микширование Singleton.

require 'singleton'

class Pubnub
  include Singleton

  attr_writer :publish_key, :subscribe_key, :secret_key, :ssl_on

  def publish
    #...
  end
end

а затем используйте его следующим образом:

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

Вы также можете сделать его переменной класса, чтобы связать его более тесно с определенной моделью:

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