2016-04-08 74 views
0

這發生在我的Rails應用程序中,但我不確定這是Rails問題還是我誤解了多部分表單應該工作。以多部分形式提交空字符串作爲空字符串,不爲空

這裏的(像)我的表格:

<%= form_for @user do |f| %> 
    <%= f.text_field :name %> 
    <%= f.submit %> 
<% end %> 

User#name有存在驗證。如果我訪問users/1/edit,請清空'name'文本字段的值,然後單擊submit,由於存在驗證失敗,因此不會更新任何內容。到現在爲止還挺好。

但現在我已經添加了一個avatar屬性我的用戶(使用回形針寶石用於文件存儲),所以我更新相應的形式:

<%= form_for @user do |f| %> 
    <%= f.text_field :name %> 
    <%= f.file_field :avatar %> 
    <%= f.submit %> 
<% end %> 

現在,如果我去編輯用戶併爲name提交空白值,驗證不會失敗。 User#name保持以前的值,但更新仍然看起來成功(即我沒有收到有關驗證失敗的錯誤消息,並且數據庫中的updated_at時間戳得到更新。)

仔細觀察,似乎是我在表單中包含file_field,它會在提交空白文本字段時更改表​​單的行爲(可能是由於form_for現在輸出的格式爲enctype=-"multipart/form-data")。

file_field目前,提交空白name發送這些PARAMS到服務器:

{ "id" => 1, "user" => { "name: "" }

導致控制器,這當然無法更新像User.find(1).update_attributes(name: "")因爲Rails認爲我們試圖將'name'更新爲空字符串,並且驗證失敗。

目前,這種被提交:

{ "id" => 1, "user" => { }(加上約化身文件額外的信息)

的「姓名」鍵不存在可言,所以控制器運行User.find(1).update_attributes()這當然會通過,因爲沒有任何更新可能會導致驗證失敗。

這是一個錯誤或功能?爲什麼要將enctype改爲multipart(假設這是問題的根源)會改變空白文本字段的行爲方式? (我已經在Chrome和FF,fwiw中對此進行了測試)。如果這確實是預期的行爲,我如何確保空白文本字段得到正確提交,而無需在每個文本字段中添加一堆繁瑣的樣板文件?

(如果有問題,我使用:Ruby 2.3.0,Rails 5.0.0.beta3,Paperclip 5.0.0。β1,我已經在Chrome 49和Firefox 45)

+0

奇怪的是,我無法重現你描述的行爲。在我的情況下(Rails 4.2雖然),無論編碼類型是什麼形式,空名都是_always_作爲空字符串發送:'「name」=>「」''。也許你可以在Rails 4上嘗試相同的代碼,以便可能發現Rails 5的行爲變化(甚至是bug)? – BoraMa

+0

另請參閱我認爲需要的[my edit](http://stackoverflow.com/posts/36501726/revisions),以便如果我誤解了您,問題實際上是有意義的,並將其還原。 – BoraMa

+0

是的,你的編輯是正確的。感謝您捕捉我的錯誤。 – GMA

回答

1

我有同樣的問題,更新Rails的最新版本修復它。

+0

是的,我正在使用Rails 5.0.0的測試版本之一。升級到RC似乎已經修復了它。 – GMA

0

測試,我認爲你可以做這樣的事情

updated_user = User.new(your_params) # The new attributes is set to a new object record  
target_user = User.find(params[:id]) # the user you want to update 
target_user = updated_user 

    if target_user.save? 
    .. 
    else 
    .. 

通過這一切的驗證將被觸發,活動記錄將所有的新屬性,如果名稱爲空白,它會抓住它

+0

不起作用。你的前三行在功能上等價於'target_user = User.new(your_params)',它將創建一個新用戶,而不是更新現有用戶 - 問題不在於'用戶'無法捕獲空白名稱,問題當它不應該的時候,'params [:user] [:name]'首先是空白的(':name'不存在)。 – GMA

+0

是的,現在我明白了,聽起來很奇怪,你是否嘗試過其他類似carrierwave的寶石,並且發生了同樣的行爲? – amrdruid

0

下強PARAM方法不會帶回下降:名稱參數,但應防止形式從模仿成功提交:

private 
    def user_params 
    params.require(:user).permit(:name, :avatar) 
    end 

這可以作爲您的用戶控制器下的私有方法插入。然後只需在Update方法中調用user_params。

+0

這不回答我的問題。我已經有了強參數的'_params'方法。 – GMA