2012-05-20 76 views
0

我有類似問題跟蹤系統的問題,他們有一些問題。保存update_attributes上的引用資源(在編輯時創建嵌套資源)

現在在一個頁面上,我想給用戶一個選項來編輯「問題」的一些東西,以及添加評論。編輯和發佈是一個標準的東西,如/編輯,但我也想創建一個評論,並驗證它是否不是空白。

我已經知道我可以構建一個評論併爲它創建一個表單,但我應該如何同時檢查問題屬性和註釋屬性是否有效?因爲每個更新都應該有一個新評論,但如果問題屬性無效,我不想創建新評論。

回答

0

我會通過首先將fails_validation?方法添加到IssuesComments型號來檢查問題。

其次,你會從params[]手動加載@issue表單數據並驗證它之前,你保存它(不能使用update_attributes(params[:issue]))創建一個新的Comment並通過params[]加載它。然後,您可以在兩個模型上測試驗證,如果其中一個失敗,請返回edit操作。

如果兩次通過,您可以保存@issue,然後@comment正常。

def update 
    @issue = Issue.find(params[:id]) 
    # manually transfer form data to the issue model 
    @issue.title = params[:issue][:title] 
    @issue.body = params[:issue][:body] 
    #... 

    @comment = @issue.comments.new(params[:comment]) 

    # validate both @issue and @comment 
    if @issue.fails_validation? || @comment.fails_validation? 
    flash[:error] = "Your edits or your comment did not pass validation." 
    render :action => "edit", 
    end 

    # validation passed, save @issue then @comment 
    respond_to do |format| 
    if @issue.save 
     @comment.save 
     format.html { redirect_to @issue, notice: 'Issue successfully updated. Comment created' } 
     format.json { head :ok } 
    else 
     format.html { render action: "edit" } 
     format.json { render json: @issue.errors, status: :unprocessable_entity } 
    end 
    end 
end 

不是最優雅的解決方案,但它應該工作。

+0

你爲什麼說update_attributes方法不會檢查驗證錯誤?它調用內部運行驗證的保存。 – Salil

+0

這是一個邏輯流問題,而不是update_attributes()功能問題。如果你使用update_attributes(),它會從params []加載你的模型並保存它(你是正確的)。但是,在這個問題中,你想從params []加載你的模型,但不要保存它,直到你有對通過params []進入的數據進行驗證。這就是爲什麼我發表評論說你不能使用update_attributes() - 因爲它會在驗證param []更新之前保存你的模型。 –

+0

@salil - 我假設他沒有使用嵌套屬性,因此需要單獨的驗證過程。如果他使用嵌套屬性,那麼你的答案顯然是首選方法。 –

0

您可以在各自的類中驗證評論模型和問題模型。 我不清楚您是否在發佈評論時使用'accep_nested_attributes_for'。如果是,那麼如果問題無效,標準IssueController#update將不會保存記錄,因此它也不會創建評論記錄。

下面是標準IssueController#更新:

class IssueController < ApplicationController 

    def update 
    @issue = Issue.find(params[:id]) 
    if @issue.update_attributes(params[:issue]) 
     redirect_to issues_path, notice: 'issue updated' 
    else 
     render action: 'edit' 
    end 
    end