Расширение рубиновой жемчужины в Rails - PullRequest
6 голосов
/ 06 января 2010

Допустим, у меня есть приложение Rails, которое получает большинство своих функций от гема (например, CMS).

Если мне теперь нужно добавить некоторые настройки (например, добавить свойство для пользователя), каков наилучший способ сделать это? Если я настрою драгоценный камень, у меня будут проблемы с обновлением драгоценного камня в будущем.

Каков наилучший подход здесь?

Ответы [ 2 ]

17 голосов
/ 05 января 2011

Этот вопрос довольно старый, но я чувствую, что он может быть немного более конкретным. Это правда, что вы можете обезьяны рельсы (и рубин) во время выполнения. Это означает, что легко открыть класс или модуль и внедрить новый код. Тем не менее, это несколько сложнее в рельсах из-за всей динамической загрузки и выгрузки классов, которые идут в режиме разработки.

Я не буду вдаваться в подробности, но вы действительно хотите поместить свои расширения в инициализатор или гем, поскольку они перезагружаются между запросами в режиме разработки. Если вы поместите код в плагин, он не будет перезагружен, и вы получите очень загадочные ошибки, такие как «Копия XXX была удалена из дерева модулей, но все еще активна!»

Самое простое, что нужно сделать, это выбросить код в инициализатор (например, config / initializers / user_extensions.rb). Вы можете просто использовать class_eval для внедрения кода.

User.class_eval do
  ... new code ...
end

Одним из основных недостатков расширяемости ruby ​​является отслеживание того, откуда поступает код. Возможно, вы захотите добавить какое-то сообщение в журнал о загружаемых расширениях, чтобы люди могли его отследить.

Rails.logger.info "\n~~~ Loading extensions to the User model from #{ __FILE__ }\n"
User.class_eval do
  ... new code ...
end

Дальнейшее чтение:

http://airbladesoftware.com/notes/monkey-patching-a-gem-in-rails-2-3

1 голос
/ 06 января 2010

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

Обновление:

Обратите внимание, что эти настройки зависят от приложения

Да. Я имел в виду модифицировать общий API таким образом, чтобы его можно было настроить для каждого приложения. Например, разрешив пользователю передать блок определенным методам и т. Д.

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