2011-12-31 42 views
1

比方說,我有一個匹配兩個人對抗的應用程序,有點像「不熱」。如何在同時更新Rails中的兩個模型?

我有我的對手視圖拉出隨機用戶的數據庫和匹配他們對彼此。當用戶爲其中一個人投票時,我想將他們的:wins:matches_played增加1,但是我也想將失敗者:matches_played增加1,以便我可以計算排名。

是否有一種方法可以爲每個人使用表單來完成此操作,還是需要在兩者之間建立模型,比如匹配項,其中包含兩列勝者和失敗者,如果是這樣,將如何工作。

+0

我會將這些信息分離到一個「匹配」表中,並執行一些SQL來計算您想要的值。 – Reactormonk 2011-12-31 15:22:05

回答

3

否則它只能使用人民模型(以下簡稱「易」的方式):

  • Pro的:它很容易
  • 反對的:這很容易讓人們誇大自己的「勝利」,由使用Firebug或Chrome的檢測工具鍛造表格的參數

假設您有這些路線:

new_person GET  /people/new(.:format)  {:action=>"new", :controller=>"people"} 
edit_person GET  /people/:id/edit(.:format) {:action=>"edit", :controller=>"people"} 
person  GET  /people/:id(.:format)  {:action=>"show", :controller=>"people"} 
      PUT  /people/:id(.:format)  {:action=>"update", :controller=>"people"} 
      DELETE /people/:id(.:format)  {:action=>"destroy", :controller=>"people"} 

HAML視圖代碼的版本:

- # Person A form 
= form_tag(person_path(@personA, :loser_id => @personB), :method => :put) do 
    = submit_tag "Vote for Person A" 

- # Person B form 
= form_tag(person_path(@personB, :loser_id => @personA), :method => :put) do 
    = submit_tag "Vote for Person B" 

ERB版本:

<%# Person A form %> 
<% form_tag(person_path(@personA, :loser_id => @personB), :method => :put) do %> 
    <%= submit_tag "Vote for Person A" %> 
<% end %> 

<%# Person B form %> 
<% form_tag(person_path(@personB, :loser_id => @personA), :method => :put) do %> 
    <%= submit_tag "Vote for Person B" %> 
<% end %> 

然後在您的控制器爲update行動,你可以這樣做:

def update 
    People.transaction do 
    winner = People.find(params[:id]) 
    loser = People.find(params[:loser_id]) 

    # Increment the winner 
    winner.increment! :matches_played 
    winner.increment! :wins 

    # Increment the loser 
    loser.increment! :matches_played 
    end 

    respond_to do |format| 
    format.html { redirect_to new_match_path } 
    end 
end 

由於有人在評論中指出,你應該換行這就是所謂的transaction,因此只有在事務處理中的所有事情都能成功保存時,它纔會永久存在於數據庫中。


即使我展示你以上的方法,我還是建議使用Match模型。最終,使用該額外模型將幫助您驗證以下事項,以便人們無法對您的系統進行遊戲。

  • 用戶只能每場比賽投一次
  • 用戶對涉及他們
  • 匹配用戶不能投票不能僞造的形式儘可能模式去誇大他們的勝
  • 獨立的關切並且使您的數據更有條理,清晰的分析目的

是的,這一切都需要更多的工作(這就是爲什麼我不表示它的代碼),但它可能是你想要的,如果你做一些事情」關心任何ab OVE。

+0

非常感謝,非常全面和清晰的答案。快速的問題,我確實有這些路線(我相信來自資源:人),這是否意味着提交一個表單:方法=>:放自動使用更新操作? – Zach 2011-12-31 18:00:47

+0

出於好奇,你會如何將haml轉換爲erb?它會是一個具有相同論點和隱藏領域的形式嗎?不太確定它應該看起來如何。 – Zach 2011-12-31 20:26:52

+0

嘿扎克,對於遲到的回覆感到抱歉。你對':put'方法是正確的。如果您查看路由列表,那麼兩個底層路由名稱中沒有路徑幫助程序名稱,這意味着它們使用上面的路徑幫助程序名稱(即「person」,然後將'_path'追加到末尾對於路徑助手...如果你想要的URL,你會追加'_url') – iwasrobbed 2012-01-01 15:20:37

0

你應該寫你的表單提交以提交用戶id到你的控制器,並顯示獲勝的用戶。然後你可以對它們進行操作並將它們保存到數據庫中。

winner = People.find(params[:winner_id]) 
loser = People.find(params[:loser_id]) 
winner.matches_played += 1 
winner.wins += 1 
loser.matches_played += 1 
winner.save! 
loser.save! 
+0

我會如何在控制器中提供這些參數? – Zach 2011-12-31 07:50:20

相關問題