覆盖/修改 Rails 类 (ActiveResource) [英] Overriding/Modifying Rails Class (ActiveResource)

查看:31
本文介绍了覆盖/修改 Rails 类 (ActiveResource)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力解决 ActiveResource 的一个问题:当主机名解析 ActiveResource 请求,但另一端没有服务器返回信息时,ActiveResource 的超时值不起作用.请求只是挂起.

在查看 ActiveResource 代码后,我意识到这是因为底层 Net:Http 对象只设置了一个超时值:read_timeout.Net:Http 库将其定义为等待读取一个块(通过一次 read(2) 调用)的秒数".Net:Http 库还定义了另一个超时值 open_timeout,它被定义为等待打开连接的秒数".

我不确定为什么默认情况下没有设置 open_timeout 并在 ActiveResource 类上设置超时值,但是在修改 ActiveResource::Connection 类以在 http 对象上包含 open_timeout 后,我​​的问题得到了解决!

我是 Rails 的新手,所以我不确定在我的项目中实际进行这种修改的最佳方法;我不想只更改我的 gem 目录中的代码.在 rails 项目中是否有正确的方法进行这些修改?我已经看到可以从/vendor 文件夹加载 rails 类,但是它们是否都必须在那里才能工作?我开始创建 ActiveResource::Base 和 ActiveResource::Connection 类的子类,但似乎有一种更简单的方法可以做到这一点,因为创建 Net:Http 实例的函数是私有的......有什么想法吗?

解决方案

首先,这是一个你应该向 Rails 的 bugtracker 报告的问题:https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/

当我必须修复这些小问题时,我通常会在 RAILS_ROOT/config/initializers 中创建一个初始化文件,然后重新打开我打算修复的类.

class ActiveResource::Base# 你的修复在这里结尾

这被称为猴子补丁,并且有些争议.但是我个人认为在继承层次结构中引入一个对我的代码没有语义意义的新级别是非常残酷的.

I've been struggling with an issue with ActiveResource for a bit now: when a hostname resolves for an ActiveResource request, but there's no server on the other end to return information, ActiveResource's timeout value doesn't work. The request just hangs.

After reviewing the ActiveResource code, I've realized that this is because the underlying Net:Http object only has one timeout value set: read_timeout. The Net:Http library defines this as "Seconds to wait until reading one block (by one read(2) call)". The Net:Http lib also defines another timeout value, open_timeout, which is defined as "Seconds to wait until connection is opened".

I'm unsure why open_timeout isn't set by default with the timeout value set on an ActiveResource class, but after modifying the ActiveResource::Connection class to include the open_timeout on the http objects, my issue was resolved!

I'm new to rails so I'm unsure of the best way to actually make this modification in my project; I don't want to just change the code in my gem directory. Is there a proper way to make these modifications in a rails project? I've seen that it's possible to load rails classes from the /vendor folder, but do they all have to be there for it to work? I started to make subclasses of the ActiveResource::Base and ActiveResource::Connection classes, but it seemed like maybe there was an easier way to do this, as the function that creates the Net:Http instance is private...any thoughts?

解决方案

First of all, this is an issue you should report to Rails' bugtracker: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/

When I have to hotfix minor things like these, I usually create an initializer file in RAILS_ROOT/config/initializers and reopen the class I intend to fix.

class ActiveResource::Base
  # your fix goes here
end

This is called monkey patching and is somewhat controversial. But I personally consider it quite brutal to introduce a new level into the inheritance hierarchy that has no semantical meaning to my code.

这篇关于覆盖/修改 Rails 类 (ActiveResource)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆