2014-11-02 61 views
2

我有一個表單來創建一個具有所有常用屬性的用戶模型,但是我也傳遞了很多非模型屬性,這些屬性基於我將在我的控制器操作中創建更多的東西。Rails強參數:如何接受模型和非模型屬性?

我的問題是我如何告訴Strong參數接受用戶數據和這個與用戶db無關的其他數據?

爲了說明,我的方式都喜歡這樣的(提交按鈕brievity刪除):

<%= form_for @user do |f| %> 
    <%= f.text_field 'attribute1' %> 
    <%= f.text_field 'attribute2' %> 
    <%= f.text_field 'attribute3' %> 

    <%= text_field_tag 'attribute_not_on_user_model1' %> 
    <%= text_field_tag 'attribute_not_on_user_model2' %> 
<% end %> 

如何使用強大的參數來做到這一點?我嘗試這樣做:

params.require(:user).permit(:attribute1, :attribute2 , :attribute3, :attribute_not_on_user_model1, 
    attribute_not_on_user_model2) 

而且也是這樣:

params.require(:user).permit(:attribute1, :attribute2 ,  
    :attribute3).require(:attribute_not_on_user_model1, 
    attribute_not_on_user_model2) 

兩人都沒有工作。我知道我可以在用戶中執行attr_accessor,但是我在此表單中列出的屬性與用戶模型本身無關(但對於創建用戶模型及其後續相關模型)。我們可以辯論這不是做這件事的最好方法(想到一個表單對象),但是現在我想看看Strong Parameters是否可以幫助我。

回答

3

user模型屬性存儲在:user散列內,而非用戶屬性可以直接在params級別訪問。

如果您檢查您的params哈希,你會發現,它是通過以下方式

{ user: { attribute1: "value", attribute2: value, ... }, attribute_not_on_user_model1: "value", attribute_not_on_user_model2: "value" } 

因此構成,呼叫

params.require(:user) 

將自動忽略任何其他PARAM不是一部分的user節點。如果您還想包含其他參數,則可以組成散列,或更新視圖以在表單中注入參數。

在窗體上注入參數將導致參數成爲同一節點的一部分。這種方法通常對虛擬屬性非常有效(儘管概念之間沒有關聯)。

<%= form_for @user do |f| %> 
    <%= f.text_field 'attribute1' %> 
    <%= f.text_field 'attribute2' %> 
    <%= f.text_field 'attribute3' %> 

    <%= text_field_tag 'user[attribute_not_on_user_model1]' %> 
    <%= text_field_tag 'user[attribute_not_on_user_model2]' %> 
<% end %> 

其他的解決辦法是像

def some_params 
    hash = {} 
    hash.merge! params.require(:user).slice(:attribute1, :attribute2, :attribute3) 
    hash.merge! params.slice(:attribute_not_on_user_model1, 
    attribute_not_on_user_model2) 
    hash 
end 

的解決方案,但是,實際上取決於這些PARAMS你將如何用戶以後。如果所有這些參數都是作爲單個散列發送的,那麼您可能需要編寫單個散列,但在這種情況下,您可能還需要虛擬屬性。

問題是,如果沒有真正的用例,問題本身就是無意義的。 StrongParameters旨在過濾傳遞給批量創建或批量更新操作的一組參數。一般來說,這意味着你有一個模型。

如果您設計了自定義方法,或者如果您有非模型方法,則由於您可以控制正在編寫和調用的方法,因此StrongParameters白名單可能沒有任何意義。

+0

非常有意義。謝謝。 – 2014-11-02 20:23:50

+0

所以構造的散列似乎是要走的路,因爲如果你任意地將該參數添加到用戶,除非你也將它添加到數據庫,它會拋出一個'UnknownAttributeError',並將其添加到數據庫似乎擊敗目的的練習。我也試圖在Devise上下文中構建哈希構造方法...不太確定如何,如果您可以評論,會喜歡它:http://stackoverflow.com/questions/30420211/customizing-devise-parameter-消毒劑對接受 - 無論模型 - 非模型attribut – james 2015-05-24 04:57:14