1

我正在使用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 页面。我在任何地方都没有找到解决方案,如果有人可以帮助我解决这个问题,我将不胜感激。

4

3 回答 3

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 代码的结构。

于 2011-04-26T14:41:09.217 回答
2

您永远GET不应该对服务器进行任何更改。一些浏览器甚至“预取”页面上链接的数据,因此它可以在用户不知道的情况下在服务器上进行更改。

每当要在服务器上进行任何更改时始终使用 a POST,并且浏览器将再次询问用户是否要再次提交请求。

在 CRUD - Create, Retrieve, Update, and Delete 中,只有 Retrieve 应该被使用GET,其他的都是通过POST. PUT有关于使用and的说法DELETE,但在实践中,它是通过POST使用_method参数或类似名称来完成的。

请参阅:为什么 Ruby on Rails 书籍或参考资料总是说 Update 是 PUT 而 Destroy 是 DELETE 而不是?

于 2011-04-25T04:58:15.237 回答
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 请求。

于 2011-04-26T14:10:34.187 回答