A Rails 3 Engine-Gem, который также является Приложением, хочет использовать DRY-конфигурацию через Mixin. - PullRequest
0 голосов
/ 11 мая 2011

У меня есть несколько движков, которые также являются гемами и приложениями (Rails3). Они являются гемами, поэтому их можно легко установить и управлять зависимостями через несколько пакетов в нескольких приложениях (это целый стек, на котором построено несколько приложений). Они являются двигателями для использования ресурсов Rails - моделей и тому подобного. Они являются приложениями по двум причинам: 1) для обеспечения полной среды тестирования, которая изолирована от их включающих приложений, чтобы вы могли, например, выполнить 'rails c', и 2) для запуска таких вещей, как 'rake db: migrate' и seed, и Больше.

Я хочу, чтобы и мой движок, и мое приложение добавляли некоторые миксины в зависимости более низкого уровня. Вот решение, которое я придумал. Это работает нормально - мне просто интересно, есть ли у кого-нибудь критика подхода или лучшая практика, чтобы поделиться в отношении проблемы совместного использования или общей идеи engine-gem-application:

Двигатель:

#my_engine/lib/my_engine.rb
require 'my_engine/config.rb'
module MyEngine
  class Engine < Rails::Engine
    config.to_prepare do
      MyEngine.inject_mixins
    end
  end
end

Заявка:

#my_engine/config/application.rb
require 'my_engine/config'
module MyEngine
  class Application < Rails::Application
    config.to_prepare do
      MyEngine.inject_mixins
    end
  end
end

Миксин:

#my_engine/lib/my_engine/config.rb
module MyEngine
  module CLASSMETHODS
    def inject_mixins
      ::ApplicationHelper.send(:include, MyEngine)
      ::SomeDependency::SomeClass.send(:include, MyEngine::SomeClassMixin)
    end
    #root should be defined as the root of this engine, ie relative to this file 
    def root
      File.join(File.dirname(__FILE__), '..','..')
    end
  end
extend CLASS_METHODS
end

(Обновление: я изменил вышеупомянутое, чтобы обернуть модуль в модуле my_engine, иначе более чем один движок, использующий этот шаблон одновременно, может иметь непредсказуемые эффекты, такие как MyEngine.root == SomeOtherEngine.root)

1 Ответ

1 голос
/ 13 мая 2011

Нет рифмы или правила для этого, но у вас есть пара разных вариантов.

Тесты вашего драгоценного камня могут содержать фиктивное приложение для тестирования.Devise делает это, например.Это общепринятая практика для драгоценных камней, которые сильно зависят от Rails.

Вы также можете хранить их отдельно.В прошлом я устанавливал тестовое приложение с Gemfile, которое указывает на гем через путь (gem 'mygem', :path => 'some/path'), что делает тестирование относительно простым.Это может удвоиться как пример приложения, которое вы можете предоставить в отдельном репозитории (имейте в виду, что при пометке драгоценного камня вы должны изменить параметр образца пути: path на конкретную версию).Преимущество здесь в том, что ваше приложение всегда обновляется.

Если вы просто говорите о моделях модульного тестирования, вы можете пропустить вышеупомянутое и просто добавить зависимость тестирования от Active Record и SQLite.Сохраняйте данные о приборах с помощью самоцвета.

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

...