覆盖或添加已加载的类的方法

时间:2016-05-07 00:17:44

标签: ruby-on-rails ruby activesupport

我正在尝试向ActiveSupport :: TimeWithZone类添加功能,将以下文件添加到我的rails项目中:

LIB / active_support / time_with_zone.rb

config.autoload_paths << "#{Rails.root}/lib"

并在

配置/ application.rb中

{{1}}

我可以在我的lib目录中使用其他自定义模块,但是这个模块似乎被忽略了。知道为什么吗?

enter image description here

3 个答案:

答案 0 :(得分:1)

所有猴子补丁通常存储在config/initializers目录中。 我将您的代码放在config/initializers/active_support_time_with_zone.rb

这是我的例子

2.1.2 :005 > r = Reason.last
  Reason Load (0.1ms)  SELECT "reasons".* FROM "reasons" ORDER BY "reasons"."id" DESC LIMIT 1
 => #<Reason id: 3, name: "R3", project_id: 3, created_at: "2016-05-04 06:43:25", updated_at: "2016-05-04 06:43:25", deleted: false>
2.1.2 :006 > r.created_at.class
 => ActiveSupport::TimeWithZone
2.1.2 :007 > r.created_at.in_time_zone_
 => Wed, 04 May 2016 06:43:25 UTC +00:00
2.1.2 :010 > Time.zone = "Novosibirsk"
 => "Novosibirsk"
2.1.2 :011 > Time.zone
 => #<ActiveSupport::TimeZone:0x007fbcd695ad90 @name="Novosibirsk", @utc_offset=nil, @tzinfo=#<TZInfo::TimezoneProxy: Asia/Novosibirsk>, @current_period=nil>
2.1.2 :012 > r.created_at.in_time_zone_
 => Wed, 04 May 2016 13:43:25 NOVT +07:00
2.1.2 :013 >

我使用了您提供的代码

class ActiveSupport::TimeWithZone
  def in_time_zone_(new_zone = ::Time.zone)
    Time.zone.parse(in_time_zone(new_zone).strftime('%a, %d %b %Y %H:%M:%S'))
  end
end

我的应用使用gem 'rails', '4.0.3'

希望有所帮助。

答案 1 :(得分:1)

实际上Rails比你想象的要聪明,你放入autoload_paths数组的路径是为了将来使用。如果放development,则在eager loading环境off个类中。因此,只有在编码需要时,类才会加载到内存或required中。

如果需要,Rails会在fileclass之后搜索namespace

示例
如果它看到ActiveSupport::TimeWithZone,则它期望路径为 lib/active_support/time_with_zone.rb

lib因为您将lib目录放在数组中。

initializers目录不是这种情况。因为当Rails启动时,此目录中的所有文件都被认为是重要的并且已加载。

有关详情,请参阅此处 http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths

答案 2 :(得分:0)

当您尝试使用未定义的常量时,Rails为您加载代码:调用override func viewDidDisappear(animated: Bool) { createLocalNotification() } func createLocalNotification(){ let localNotification = UILocalNotification() localNotification.fireDate = reminders.time! localNotification.alertBody = reminders.name! UIApplication.sharedApplication().scheduleLocalNotification(localNotification) } 挂钩设置,在const_missing中搜索名称与常量对应的文件,然后需要它。

在您的情况下,永远不会调用此代码:在加载rails本身期间加载autoload_paths类。

您可以将猴子补丁放在总是被加载的东西中(例如在初始化器中),或者从初始化器中明确要求它。