ОБНОВЛЕНИЕ: я добавил сообщение в блоге на основе этого ответа, но с гораздо более подробной информацией: http://thoughtsincomputation.com/posts/coding-an-acts_as-gem-for-rails-3
-
Я не знаю другого учебного источника, но вот несколько общих советов.
Rails 3 использует действительно полезную функцию под названием Railtie - см. http://api.rubyonrails.org/classes/Rails/Railtie.html.
Так что, если бы я реализовывал гем act_as_ *, я бы начал там. Мой рельс может выглядеть примерно так:
# lib/acts_as_awesome/railtie.rb
require 'rails'
require 'acts_as_awesome'
module ActsAsAwesome
class Railtie < Rails::Railtie
config.to_prepare do
ApplicationController.send(:extend, ActsAsAwesome::Hook)
end
end
end
и ActsAsAwesome :: Код хука:
# lib/acts_as_awesome/hook.rb
module ActsAsAwesome::Hook
def acts_as_awesome(*args)
options = args.extract_options!
# do the things that make the controller awesome.
include ActsAsAwesome::InstanceMethods
before_filter :an_awesome_filter
end
end
Я чувствую, что концепции здесь здравы и использовали подобные процессы раньше. По сути, он сказал бы, чтобы Rails выполнял блок to_prepare один раз во время производства и перед каждым запросом в разработке (мы хотим этого, потому что ApplicationController будет перезагружен в это время, потенциально уничтожая наш метод подключения); и ловушка просто так: она добавляет ловушку ко всем контроллерам (или, точнее, ко всем контроллерам, которые расширяют ApplicationController), чтобы позволить пользователю вводить настоящий «удивительный» код в свои контроллеры, не влияя иначе на контроллеры, которые в нем не нуждаются.
Хук #acts_as_awesome сам по себе не передает функциональности Awesome. Это потому, что не всем контроллерам может понадобиться эта функциональность. Вместо этого метод отвечает за представление real удивительных вещей через модуль ActsAsAwesome :: InstanceMethods. Таким образом, пользователь получает функциональность Awesome только в том случае, если он явно вызывает метод acts_as_awesome. Он также добавляет в контроллер фильтр before, чтобы продемонстрировать, что код в этом методе будет оцениваться точно так же, как если бы он был в самом классе целевого контроллера.
Этот метод должен работать точно так же, если вы нацеливаетесь на модели, а не на контроллеры: просто вставьте свой хук в ActiveRecord :: Base. Поскольку AR: B загружается только при загрузке Rails, вы, вероятно, сможете поместить это в инициализатор (см. Документацию Railtie), но я оставляю за собой право ошибиться здесь.
Понятно, что касается railtie: документация гласит, что она должна быть автоматически обнаружена, но у меня часто возникают проблемы с этим. Чтобы обойти это, просто потребуйте railtie из основного исходного файла вашего драгоценного камня (в приведенном выше примере это будет lib / acts_as_awesome.rb).
Вы можете увидеть весь источник ActsAsAwesome во всей его красе на моем аккаунте на github:
http://github.com/sinisterchipmunk/acts_as_awesome
Надеюсь, это полезно. Ваш вопрос был несколько высокоуровневым, поэтому я могу ответить на высоком уровне.
-Колин МакКензи IV
http://thoughtsincomputation.com
@ sinisterchipmnk