在Rails中扩展ruby gem

时间:2010-01-06 11:00:07

标签: ruby-on-rails rubygems

假设我有一个Rails应用程序,它可以从gem中获取大部分功能(例如,CMS)。

如果我现在需要添加一些自定义(例如,向用户添加属性),这样做的最佳实践方法是什么?如果我自定义gem,那么我将来会有更新gem的问题。

在这里采取的最佳方法是什么?

2 个答案:

答案 0 :(得分:17)

这个问题相当陈旧,但我觉得它可以使用更多的充实。确实,你可以在运行时monkeypatch rails(和ruby)。这意味着重新打开类或模块并注入新代码很容易。但是,由于所有动态类加载和卸载都在开发模式下,这在rails中有点棘手。

我不会详细介绍,但您确实希望将扩展程序放入初始化程序或gem中,因为它们在开发模式下的请求之间重新加载。如果你将代码放入插件中,它将不会被重新加载,你会得到非常神秘的错误,例如“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 :(得分:1)

Ruby允许您在运行时扩展类,因此您通常可以在不触及源代码的情况下入侵库。否则我建议您下载gem,在库中创建一些钩子并将其作为补丁提交回来。

<强>更新

  

请注意,这些自定义是特定于应用程序的

是。我的意思是以某种方式修改通用API,以便可以根据应用程序进行自定义。例如,允许用户将块传递给某些方法等。