2017-03-12 75 views
2

我正在製作可在多個頁面中重複使用的表單。用戶可以發送一封包含此表單的電子郵件以及它自己保存在數據庫中的消息。Rails - 如何在共享表單上顯示驗證錯誤

我有這種形式兩個簡單的驗證,而這種形式也越來越顯示以及錯誤:

<%= simple_form_for @message do |f| %> 
    <%= f.input :email, error: "E-mail can't be empty" %> 
    <%= f.input :text, error: "Text can't be empty" %> 
    <%= f.button :submit %> 
<% end %> 

如果我想我的形式是在多個頁面上重複使用的比我更需要將其更改爲:

<%= simple_form_for Message.new do |f| %> 
    <%= f.input :email, error: "E-mail can't be empty" %> 
    <%= f.input :text, error: "Text can't be empty" %> 
    <%= f.button :submit %> 
<% end %> 

窗體和驗證仍然適用於此窗體,但它不顯示錯誤。我希望有人能幫助我。

+1

爲什麼不能使用表單的第一個版本?第二個版本不會顯示任何錯誤,因爲它總是處理'Message'的新實例 – Iceman

+0

因爲如果我在'new'頁面以外使用'@ message'。它會崩潰。 –

回答

1

一個可能的解決方案是在ApplicationController中創建一個方法,該方法創建@message變量,然後在每個需要顯示錶單的操作上調用它。

class ApplicationController < ActionController::Base 
    # .. 
    def load_message_for_form 
    if params[:message] 
     @message = Message.new(message_params) 
    else 
     @message = Message.new 
    end 
    end 

    def message_params 
    params.require(:message).permit(:email, :text) # add what you need 
    end 
end 

,然後在行動,你需要的形式

class UsersController < ApplicationController 
    before_action :load_message_for_form, only: [:index, :new] #change this to suit your needs 
end 

編輯: 雖然這種解決方案確實工作得非常好,應該注意不要過度使用它,因爲ApplicationController很快就會被overcluttered與這樣的東西。但對於簡單的情況,這沒關係。

+0

它的工作:)非常感謝! –

+0

是的,它確實有效,但真的要小心,不要因爲這些解決方案而陷入困境。如果你發現自己把許多東西放到application_controller中,你必須重新思考你的解決方案。但對於簡單的情況,這沒關係。 – Iceman

1

問題是,驗證後需要無效的對象來顯示錯誤。

使用共享表單通常意味着您希望能夠在任何地方展示一個用於創建某個模型實例的表單。
這就是你的第二種形式的好處。
這就是爲什麼你使用Message.new

現在,如果某些驗證失敗,您的控制器需要重新顯示包含此無效實例的表單。
這隻能使用表單的第一個變體完成。

那麼如何重新顯示正確的表單?

  • 當保存時發生錯誤時顯示正常的「新」視圖。這會將您的新對象從最初嵌入的內容文本中剔除,但可能是一種好方法

  • 處理您使用AJAX提交共享表單並將共享表單替換爲您的控制器的響應,這是一些如果成功,請點擊「確定」,如果有錯誤,請點擊表單的第一個變體。

第二個意思是這樣的:

<%= simple_form_for Message.new, remote: true do |f| %> 
    <%= f.input :email, error: "E-mail can't be empty" %> 
    <%= f.input :text, error: "Text can't be empty" %> 
    <%= f.button :submit %> 
<% end %> 

,那麼你需要爲創建行動的JS處理程序,它取代了形式:應用程序/視圖/消息/ new.js.erb

$('.new_message').html('<%= escape_javascript render partial: 'form' %>'); 

成功:app/views/messages/create.js。ERB:

$('.new_message').html('Got your message!'); 

在你的控制器,你需要處理JS請求:

def create 
    @message = Message.new(message_params) 

    respond_to do |format| 
     if @message.save 
     format.html { redirect_to @message, notice: 'Message was successfully created.' } 
     format.js 
     else 
     format.html { render :new } 
     format.js { render :new } 
     end 
    end 
    end 

這使得所有的代碼在消息的情況下。
你不會污染ApplicationController和其他控制器,你想包括共享表單。

+0

感謝您的解釋,我會挑釁地試一試! –

+0

所以我試了一下,我工作得很好,我喜歡這種方法。它顯示消息的無效實例,但我曾經擁有的驗證錯誤不再顯示。任何想法,如果有可能顯示這些?如果他們以與他們使用相同的方式出現,會很好。 (這是通過simple_form + bootstrap完成的) –

相關問題