Как мне избежать константы, когда я хочу глобальный объект в рельсах? - PullRequest
3 голосов
/ 08 июля 2019

Я хочу добавить хранилище файлов S3 в мое приложение rails 5.Поскольку я использую heroku, я использовал их учебник , в котором говорится, что нужно просто создать константу с именем S3_BUCKET в вашем config/initializers/aws.rb, и вы можете использовать эту константу везде.

Код heroku выглядит следующим образом:

#config/initializers/aws.rb

S3_BUCKET = Aws::S3::Resource.new.bucket(ENV['S3_BUCKET'])

Проблема в том, что мне нужно переопределить эту константу, чтобы спецификации работали.

У меня есть эта альтернативарешение (которое, к сожалению, не работает):

#lib/aws_helpers/s3.rb

module AWSHelpers
  module S3
    class << self
      attr_accessor :configuration

      def configure
        self.configuration ||= Configuration.new
        yield(configuration)
      end

      def bucket
        @bucket ||= Aws::S3::Resource.new.bucket(configuration.s3_bucket)
      end
    end

    class Configuration
      attr_accessor :s3_bucket, :aws_access_key_id, :aws_secret_access_key_id
    end
  end
end
#config/initializers/aws.rb

AWSHelpers::S3.configure do |config|
  config.s3_bucket = ENV['S3_BUCKET']
  config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
  config.aws_secret_access_key_id = ENV['AWS_SECRET_ACCESS_KEY']
end

То, что я хочу иметь в контроллере, это:

AWSHelpers::S3.bucket.object(a_key)

К сожалению, это не помогает и говорит мне, чтоbucket метод не может ничего вернуть, потому что конфигурация равна nil.

Что я знаю:

  1. инициализатор aws запускается, и когда я добавляю puts во все методыЯ могу видеть правильный вывод, когда мой сервер запускается через rails s
  2. , контроллер знает о сервисном модуле, или он даже не доберется до метода bucket
  3. , код работает, когда явыгрузить содержимое config/initializers/aws.rb в контроллер

Мне бы очень хотелось узнать, почему код выше не работает.Кажется, все настроено правильно, и затем, когда я хочу использовать его в контроллере, вдруг все становится так, как будто я никогда не звонил configure.

. Я также открыт для других предложений о том, как это сделать.,Простое использование константы - не вариант, потому что его нужно изменить, чтобы спецификации работали.

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

Это дешевый трюк, но он работает.

в config/application.rb:

module YourApp
  class Application < Rails::Application

    def s3_bucket
      @s3_bucket ||= begin
        # your stuff
      end 
    end 
  end
end 

Rails.application.s3_bucket.object(a_key)
0 голосов
/ 09 июля 2019

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

Это ужасно с точки зрения реализации, но с точки зрения удобства использования это приятно. Вы можете просто сделать AWSHelpers::S3.configure do |config|, как показано в инициализаторе. Весь этот код предназначен для правильной работы семантики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...