gpt4 book ai didi

ruby-on-rails - [X,Y,Z].each {|m| 有什么区别包括 m} 并包括 X、Y、Z?

转载 作者:数据小太阳 更新时间:2023-10-29 06:52:36 24 4
gpt4 key购买 nike

注意 这最初是作为一个关于 404 错误的问题开始的,但现在是一个问题,为什么我应用的补丁会有所不同。

如何获得缓存操作以在所有引发 ActiveRecord::RecordNotFound 异常的请求上返回 404,而不仅仅是第一个请求?

例如,如果您开始一个空的 Rails 项目,添加一个产品模型和 Controller ,设置您的 database.yml,在 production.rb 中设置您的缓存后端,rake db:migrate,然后开始生产并点击站点一个不存在的对象,例如http://localhost:3000/product/show/1234

class ProductController < ApplicationController

caches_action :show

def show
@product = Product.find(params[:id])
render :text => "asdf"
end

end

第一次点击页面时,它按预期返回了 404 页面。但是,对该 URL 的每次后续点击都会返回一个带有 200 OK 的空白页面。你如何让它每次都返回 404?

这是 CURL 请求,后面是日志

~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 404 Not Found
Connection: close
Date: Mon, 20 Apr 2009 22:49:18 GMT
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 14097

~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 200 OK
Connection: close
Date: Mon, 20 Apr 2009 22:49:19 GMT
X-Runtime: 6
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 0

第二个回答显然是错误的。

这是 2 个请求的日志副本:

Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:24) [GET]
Parameters: {"id"=>"1234"}

ActiveRecord::RecordNotFound (Couldn't find Product with ID=1234):
app/controllers/product_controller.rb:6:in `show'

Rendering rescues/layout (not_found)


Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:30) [GET]
Parameters: {"id"=>"1234"}
Filter chain halted as [#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>] rendered_or_redirected.
Filter chain halted as [#<ActionController::Filters::AroundFilter:0x23e3580 @kind=:filter, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>, @identifier=nil>] did_not_yield.
Completed in 12ms (View: 0, DB: 0) | 200 OK [http://0.0.0.0/product/show/1234]

确实,如果您将缓存的操作从缓存中拉出,它里面会有某种空垃圾。

cache.fetch("views/0.0.0.0:3000/product/show/1234")
=> ["", nil, [], []]

我在这里做错了什么?

编辑

我已经确认 Rails 2.1.2 和 2.2.2 没有出现这种行为,但 2.3.2 出现了。 (即旧版本不会将空响应存储到缓存中,它们确实会为后续请求抛出 404)

我在针对 edge Rails 进行测试时遇到问题,因为加载它会在启动服务器时导致以下错误:foob​​ar/vendor/rails/activesupport/lib/active_support/dependencies.rb:440:in `load_missing_constant': 未初始化常量 ActionController::Failsafe (NameError)

我已经针对 2-3-stable 分支的当前负责人 375e8976e3 进行了测试,它也表现出这种行为。

编辑#2我试图追踪 Rails 代码库中发生更改的时间以确定它是否是故意的。似乎this seemingly innocuous commit是错误开始的地方。

这里是二分的详细信息,其中 404 表示期望的行为,200 表示不需要的行为。

2-3-stable branch    375e8976e3 - 200    b1c989f28d - 200    beca1f2e15 - 200    f1fff0a48  - 200    f1e20ce9a7 - 200    a5004573d8 - 200    2e1132fad8 - 200 - the difference seems to start at this commit    c69d8c043f - 404    d961592886 - 404    276ec16007 - 404    0efec6452  - 404    13c6c3cfc5 - 404    fb2325e35  - 4042-2 stable    3cb89257b4 - 404

Here is a patch that reverses the change, which when applied to tag v2.3.2.1, i.e. dc88847e5ce392eed210b97525c14fca55852867, fixes the problem. I, however, am not smart enough to fathom why this seemingly small change would actually make a difference! Perhaps someone smarter than me could shed some light on the situation?

diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 0facf70..0790807 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -1403,12 +1403,9 @@ module ActionController #:nodoc:
end

Base.class_eval do
- [ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
- Cookies, Caching, Verification, Streaming, SessionManagement,
- HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
- RecordIdentifier, RequestForgeryProtection, Translation
- ].each do |mod|
- include mod
- end
+ include Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers
+ include Cookies, Caching, Verification, Streaming, SessionManagement
+ include HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods
+ include RecordIdentifier, RequestForgeryProtection, Translation
end
end

编辑 #3该补丁似乎还修复了上面显示的相关错误,其中“Completed in XYms (DB: Z) | 404 Not Found [http://0.0.0.0/product/1234]”没有出现在日志中。

编辑#4上面的补丁破坏了 ActionPack 中的其他东西,所以我深入研究并生成了一个不会造成附带损害的问题的修复程序。补丁和任何后续更新将位于 the rails lighthouse

最佳答案

看起来 include(X, Y, Z) 实际上以与 include X 不同的顺序运行;包括 Y;包括 Z

下面我粘贴了在 Ruby 1.8.6 中实现 Module#include 方法的 C 代码。

static VALUE
rb_mod_include(argc, argv, module)
int argc;
VALUE *argv;
VALUE module;
{
int i;

for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE);
while (argc--) {
rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
rb_funcall(argv[argc], rb_intern("included"), 1, module);
}
return module;
}

即使你不熟悉 Ruby 的 C 内部结构,也很清楚这个函数有一个 for 循环向上迭代以检查所有参数的类型是否为 T_MODULE,然后使用一个 while 循环向下迭代以实际包含模块 - 因此 include(X, Y, Z) 中的模块实际上将按 Z, Y, X 的顺序包含。我没有遍历所有有问题的 Rails 模块,但我想一旦包含顺序被切换,就会有一些依赖于顺序的东西开始失败。

关于ruby-on-rails - [X,Y,Z].each {|m| 有什么区别包括 m} 并包括 X、Y、Z?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/770408/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com