2011-12-31 75 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

相关问题