我正在制作一个使用rails的网站,我迫切需要帮助我如何创建一个链接,点击它时会更新数据库中的属性,但只有在点击时才有。我有这样的代码:
<%= link_to (myproperty_path) do %>
<% @player.update_attribute("energy", @player.energy + 2) %><span>Take a Nap</span>
<%end%>
但问题是每当我刷新页面时它都会更新属性,当我转到网站上的另一个页面时,它会再次更新属性。当我点击它时它起作用,但我希望它只在点击时工作,就是这样。此外,如果我在同一页面上有两个这样的链接,点击一个链接就好像我同时点击了这两个链接一样。以下是myproperty页面的内容:
<%= render 'sidebar' %>
<div id="yui-main" class="yui-b">
<h2>My Property</h2>
<br \>
<p><b>Property: </b><%= @player.property %><br \><br \>
<%= link_to (myproperty_path) do %>
<span>Take a Nap</span>
<% if @player.energy <= 98 && @player.energy != 100 %>
<% @player.update_attribute("energy", @player.energy + 2) %>
<% end %>
<% end %>
<br \>
<%= link_to (myproperty_path) do %>
<span>Sleep</span>
<% if @player.energy <= 96 && @player.energy != 100 %>
<% @player.update_attribute("energy", @player.energy + 4) %>
<% end %>
<% end %>
<% if @player.property != "My Car" %>
<b>Rent: </b><br \>
<br \>
<b>Bedroom</b><br \>
<% end %>
当我点击其中一个链接时,它会为玩家的能量增加6而不仅仅是2或4. enter code here
该链接位于myproperty页面上,我希望它在点击时返回myproperty页面。
我没有在任何地方找到解决方案,如果有人能帮助我,我会非常感激。
答案 0 :(得分:8)
你正在以一种根本不正确的方式解决这个问题。 Rails不是为了在视图中提供业务逻辑 - 尤其是更新记录的逻辑!
你想要的是
<%= link_to "Take a nap", {:controller => "player_actions", :action => "nap", :id => @player.id} %>
<%= link_to "Sleep", {:controller => "player_actions", :action => "sleep", :id => @player.id } %>
在您的视图中,以及您在PlayerActionsController中的相应控制器操作,或者您想要调用它的任何操作
def nap
player = Player.find(params[:id])
player.update_attribute(:energy, player.energy + 2)
end
def sleep
player = Player.find(params[:id])
player.update_attribute(:energy, player.energy + 4)
end
这种方式只有在用户点击链接时才会发生。当然,您还需要处理任何重定向或ajax渲染,以及验证等。但这通常是您的Rails代码的结构。
答案 1 :(得分:2)
您永远不应该使用GET
对服务器进行任何更改。有些浏览器甚至“预取”页面上链接的数据,因此它可以在服务器上进行更改,而无需用户知道。
每当在服务器上进行任何更改时,始终使用POST
,浏览器将再次询问用户是否要再次提交请求。
在CRUD中 - 创建,检索,更新和删除,只有使用GET
进行检索,其他检查通过POST
完成。有关于使用PUT
和DELETE
的说法,但在实践中,它是通过POST
使用_method
参数或类似名称完成的。
答案 2 :(得分:0)
但是你继续使用HTTP动词,你的代码有一个概念缺陷:
<%= link_to (myproperty_path) do %>
<% @player.update_attribute("energy", @player.energy + 2) %><span>Take a Nap</span>
<%end%>
当您打开此页面时,@ player.update_attributes调用将在生成链接时触发一次。实际的数据库更改必须在控制器内进行(在本例中为myproperty_path的路由目标)。
此外,我完全同意您应该使用POST请求。