2012-08-22 14 views
7

docs on parameter wrapping狀態:爲什麼Rails參數包裝中不包含從URI中循環播放的東西?

裹參數散列到嵌套散列。這將允許客戶端提交POST請求,而不必指定任何根元素。

它有用地消除其中參數散列被包裹。該Action Controller overview guide給這個破敗:

的Rails收集所有與在params哈希的請求一起發送的參數,無論是作爲查詢字符串或後身體的一部分被髮送。 [...] query_parameters散列包含作爲查詢字符串的一部分發送的參數,而request_parameters散列包含作爲帖子正文的一部分發送的參數。 path_parameters散列包含的參數被路由識別爲通向此特定控制器和操作的路徑的一部分。

當您使用RESTful資源和路由時,樂趣就會發生。假設你有一個模型A has_many Bs; B因此具有外鍵a_id

POST /as/1/bs與一個空的有效載荷(因爲B沒有其他領域)。假設a_idattr_accessible,則可以假定a_id將被包裝在b對象中。相反,你會看到:

Processing by BsController#create as HTML 
    Parameters: {"b"=>{}, "a_id" => "1"} 

沒有這樣的運氣。事實證明,ParamsWrapper uses request_parameters而不是params,所以在POST有效負載中不包括a_id意味着它不會被包裝。這非常令人困惑,因爲您仍然看到它包含在params中,這是由於URI通配,並且奇怪爲什麼它排除了所有內容。

有沒有什麼好的理由在這裏使用request_parameters而不是params

我可以理解,從「REST哲學」的角度來看,如果我們假設有效載荷包含整個對象,那麼它更純粹,但這基本上意味着URI中的a_id被完全忽略,這似乎是可憐。

tl; dr:ParamsWrapper使用request_parameters作爲參數源,因此會跳過URI- globbed變量。這是一個Rails錯誤?純粹的REST倡導者可能會說不,但實用主義表明是的。

+0

你好!你有沒有想過如何解決這個問題? – dan

+1

@dan:不幸的是,自從我發佈這個問題幾個月後,我還沒有與Rails合作過,所以我一無所有! – Ashe

回答

0

據我所知,a_id未包含在'b'的散列中的原因是我們需要該id值來首先檢查記錄是否存在於我們的數據庫中。這樣,我們可以簡單地拒絕請求中的其他參數。根據不包括在'b'雜誌中的理由:它可以防止事故發生。假設有人正在更新表單並將完整的'b'散列作爲參數傳遞給模型對象。現在,當我們調用model_object.save時,它可以將記錄保存在數據庫中,而不是更新將成爲安全威脅的舊記錄(如果對象已經初始化,可能會發生)。不是一個完整的證明方案,但編碼時確實發生了事故,它可以幫助我們防止這種事故。

0

取決於您的具體的使用情況,但如果你在你的控制器使用強大的參數,可以,你可以做任何

params[:b][:a_id] = params[:a_id] 
params.require(:b).permit(:a_id) 

或只是跳過完全是「規定」的方法:

params.permit(:a_id) 
相關問題