2016-12-08 58 views
0

我正在關注this tutorial以使用Wicked gem創建多步表單。每個用戶都有一個答案(存儲對一組問題的答案的模型),並且我有一個QuestionnaireController,用於逐步解答用戶將回答並存儲在答案中的問題。到目前爲止,我只有兩個步驟,每個步驟都有一個問題(答案表上的布爾列)。當我步,並回答每一個問題的一切完美的作品,但是當我提交沒有值的獲取:Rails邪惡的多步表單 - param丟失或值爲空vs不允許的參數

參數是丟失或爲空值:答案

我的代碼...

answer.rb:

class Answer < ApplicationRecord 
    belongs_to :user 

    cattr_accessor :questionnaire_steps do 
    %w(step_one step_two) 
    end 

    attr_accessor :current_step #stores the current questionnaire step 

    validates :user_id, presence: true 

    with_options if: -> { required_for_step?(:step_one) } do |step| 
    step.validates :question_one, inclusion: [true, false] 
    end 
    with_options if: -> { required_for_step?(:step_two) } do |step| 
    step.validates :question_two, inclusion: [true, false] 
    end 

    def required_for_step?(step) 
    # All fields are required if no questionnaire step is present 
    return true if current_step.nil? 
    # All fields from previous steps are required if the 
    # step parameter appears before or we are on the current step 
    return true if self.questionnaire_steps.index(step.to_s) <= self.questionnaire_steps.index(current_step) 
    end 
end 

answers_controller.rb:

class AnswersController < ApplicationController 
    before_action :setup 

    def setup 
    @user = current_user 
    end 

    def show 
    @answer = @user.answer 
    end 

    def new 
    @answer = Answer.new 
    @answer = @user.build_answer 
    @answer.save(validate: false) 
    end 

    def create 
    @answer = @user.answer 
    redirect_to questionnaire_path(@answer, Answer.questionnaire_steps.first) 
    end 
end 

questionnaire_controller.rb:

class QuestionnaireController < ApplicationController 
    include Wicked::Wizard 

    before_action :setup 

    steps *Answer.questionnaire_steps 

    def setup 
    @user = current_user 
    end 

    def show 
    @answer = @user.answer 
    render_wizard 
    end 

    def update 
    @answer = @user.answer 
    @answer.update_attributes(answer_params(step)) 
    render_wizard @answer 
    end 

    private 

    def answer_params(step) 
    permitted_attributes = case step 
     when "step_one" 
     [:question_one] 
     when "step_two" 
     [:question_two] 
    end 

    params.require(:answer).permit(permitted_attributes).merge(current_step: step) 
    end 
end 

step_one.html.erb:

<div id="questionnaire" class="container-fluid well inline-headers"> 
    <%= form_for @answer, method: :put, url: wizard_path do |f| %> 
    <div class="row"> 
    <% if f.object.errors.any? %> 
     <div id="error_explanation" class="alert alert-dismissible alert-danger" > 
     <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> 
     <ul> 
      <% f.object.errors.each do |attribute, message| %> 
      <%= content_tag :li, f.object.errors.full_message(attribute, message), :id => "error_#{attribute}" %> 
      <% end %> 
     <ul> 
     </div> 
    <% end %> 
    </div> 
    <div class="row"> 
    <div class="col-md-8 form-group"> 
     <p>Are you any good at this?</p> 
    </div> 
    <div class="col-md-4 form-group"> 
     <%= label_tag(:question_one, "Yes") %> 
     <%= f.radio_button :question_one, true %> 
     <%= label_tag(:question_one, "No") %> 
     <%= f.radio_button :question_one, false %> 
    </div> 
    </div> 
    <div class="row"> 
    <div class="col-md-4 col-md-offset-8 form-group"> 
     <p><%= f.submit "Save & Continue", class: "btn btn-warning" %></p> 
    </div> 
    </div> 
    <% end %> 
</div> 

的routes.rb(當然我試圖讓可愛與這些掩蓋的ID,隨意羞辱我這樣做是正確的):

resources :answers, only: [:show, :new, :create] 
    get 'user/questionnaire', to: 'answers#show' 
    get 'user/questionnaire/new', to: 'answers#new' 
    post 'user/questionnaire/new', to: 'answers#create' 

resources :questionnaire 

當我選擇一個選項並提交時,它保存到數據基地和重定向到下一步,但是,如果我提交時沒有選擇一個選項,我得到的參數缺少錯誤,當我預計會得到驗證錯誤。從服務器日誌:

處理由QuestionnaireController#更新爲HTML參數: { 「UTF8」=> 「」, 「authenticity_token」=> 「J45sG/YIqTaBECgBqNLr9Ys3rJewDK78d/cKHWFHYEIzAaOiTXhgH6evPZKl5LhnSAMnQnA94CXonqriyj0fCQ ==」, 「提交」 =>「保存&繼續」,「ID」 =>「step_one」}

我已經嘗試了一些潛在的修復,包括params.require(:answer).permit(permitted_attributes).merge(current_step: step)去除require(:answer),這讓我驗證錯誤,我期待但然後不允許保存有效的值。在那種情況下我仍然得到驗證錯誤,在服務器日誌如下:在2016年12月8日23時26分14秒 處理0545開始PUT「/問卷/ step_one」爲:: 1

通過QuestionnaireController#更新爲HTML
參數:{ 「UTF8」=> 「」, 「authenticity_token」=> 「RWAHfu0BE82ik6gTChh3nmtuyOUa5j0qiz4H03ejIkRR78jHVnHa5IQsvYAHLiQMqFpDMNrXc/MUV6cs3NldDw ==」, 「回答」=> { 「question_one」=>「真「},」commit「=>」保存&繼續「, 」id「=>」step_one「} ... SQL ...未允許的參數:utf8,_method, authenticity_token,answer,commit,id

非常感謝幫助菜鳥。

更新:我修改我的路線以匹配教程(嵌套),認爲這可能與它有關(也許沒有得到答案ID),但我仍然得到的參數是缺少的錯誤。

resources :answers, only: [:show, :new, :create] do 
    resources :questionnaire, only: [:show, :update], controller: 'questionnaire' 
    end 
    get 'user/questionnaire', to: 'answers#show' 
    get 'user/questionnaire/new', to: 'answers#new' 
    post 'user/questionnaire/new', to: 'answers#create' 

我也嘗試添加一個hidden_​​field_tag之前提交,就像這樣:

<%= hidden_field_tag(:answer, @answer) %> 

但後來我得到:

未定義的方法'許可證」爲#

可能是因爲hidden_​​field_tag將@ answer.attributes作爲字符串傳遞給強壯標準ameter聲明期望散列。從服務器:

發起者QuestionnaireController#更新 爲HTML參數PUT 「/答案/ 46 /問卷/ step_one」 爲:: 1在 2016年12月12日13時25分19秒0545的處理: { 「UTF8」=> 「」, 「authenticity_token」=> 「wlLpKoMvqgyfwB5gyP/qubR4ZpZa6jm9KHeMuiwJTc6IOJZi9PgiSegvF + OzlN09ctEuxuxiAuRs +/B2InRGhA ==」, 「回答」=> 「{\」 ID \ 「=> 46,\」 USER_ID \「=> 4,\」question_one \「=>無, \」question_two \「=>無, \」percentage_complete \「=>#, \」completed \「=> false,\」created_at \「 => 2016年12月12日星期一02:12:31 EST -05:00,\「updated_at \」=> 2016年12月12日星期一02:12:31 EST -05:00}「,」commit「=>保存&繼續「,」answer_id「=>」46「,」id「=>」step_one「}

請幫忙!

回答

0

我將params.require更改爲params.fetch並且工作正常(驗證適當觸發,我也可以成功通過有效值的步驟)。

0

問題仍然有效嗎?

我想把這個評論,但不能。 我認爲問題是與vaildations。它會檢查你是否在相關領域輸入了一個值,並在沒有時會拋出錯誤。如果從模型中刪除step.validates,會發生什麼情況?

+0

仍然有效,我想我解決了它。我需要驗證,因此我將'params.require'更改爲'params.fetch',這似乎工作(驗證適當觸發,我也可以成功通過有效值的步驟)。 – CChandler81