[英]Model X and Model Y each has_many Z, :dependent => :destroy. If I destroy X, does Z get destroyed?
[英]What is the difference between [X,Y,Z].each {|m| include m} and include X, Y, Z?
注意這最初是作為一個關於404錯誤的問題開始的,但是現在這是一個問題,為什么我應用的補丁會產生影響。
如何獲得緩存操作以在所有引發ActiveRecord :: RecordNotFound異常的請求上返回404,而不僅僅是第一個請求?
例如,如果你啟動一個空的rails項目,添加一個產品模型和控制器,設置你的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)
我在測試邊緣Rails時遇到問題,因為在啟動服務器時加載它會導致以下錯誤:foobar / vendor / rails / activesupport / lib / active_support / dependencies.rb:440:in`load_missing_constant':uninitialized constant ActionController ::故障安全(NameError)
我已經對2-3穩定分支375e8976e3的當前負責人進行了測試,它也表現出這種行為。
編輯#2我試圖跟蹤Rails代碼庫中發生更改的時間,以確定它是否是故意的。 似乎這個看似無害的提交是bug開始的地方。
以下是二分的細節,其中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 - 404 2-2 stable 3cb89257b4 - 404
這是一個反轉更改的補丁,當應用於標記v2.3.2.1,即dc88847e5ce392eed210b97525c14fca55852867時,修復了該問題。 然而,我不夠聰明,不知道為什么這個看似微不足道的變化實際上會有所作為! 也許比我聰明的人可以對這種情況有所了解?
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補丁似乎也修復了上面顯示的相關錯誤,其中“在XYms中完成(DB:Z)| 404找不到[ http://0.0.0.0/product/1234] ”沒有顯示在日志。
編輯#4上面的補丁破壞了ActionPack中的其他內容,因此我深入研究並生成了一個不會導致附帶損害的問題。 補丁和任何后續更新將在軌道燈塔
似乎include(X, Y, Z)
實際上以與include X; include Y; include Z
不同的順序操作include X; include Y; include Z
include X; include Y; include Z
include X; include Y; include 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模塊,但我想有一些依賴於順序的東西,一旦切換包含順序就開始失敗了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.