Rails - 如何通过链接更改数据库值

发布于 2024-11-03 07:45:38 字数 1506 浏览 1 评论 0原文

我正在使用 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。在此处输入代码该链接位于 myproperty 页面上,我希望它返回到 myproperty 页面当点击时。 我还没有在任何地方找到解决方案,如果有人能帮助我解决这个问题,我将非常感激。

I am making a website using rails and I am in desperate need of help of how do I create a link that when clicked on it will update an attribute in the database but only when clicked on.I have this code:

<%= link_to (myproperty_path) do %>
<% @player.update_attribute("energy", @player.energy + 2) %><span>Take a Nap</span>

<%end%>

but the problem with this is that whenever I refresh the page it updates the attribute and when I go to another page on the website it updates the attribute again. It works when I click on it but I want it to work only when clicked on and that's it. Also, if I have two of these links on the same page, clicking on one link will act as if I'm clicking on both of the links at the same time. Here is what I have for the myproperty page:

<%= 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 %>

When I click on one of the links it adds 6 to the player's energy instead of just 2 or 4. enter code hereThe link is on the myproperty page and I want it to go back to the myproperty page when clicked.
I haven't found a solution anywhere, I would really appreciate it if someone could help me out with this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

再见回来 2024-11-10 07:45:38

你正在以一种根本不正确的方式处理这件事。 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 代码的结构。

You are going about this in a fundamentally incorrect way. Rails is not designed to have business logic in your views - especially logic that updates records!

What you want is something like

<%= link_to "Take a nap", {:controller => "player_actions", :action => "nap", :id => @player.id} %>
<%= link_to "Sleep", {:controller => "player_actions", :action => "sleep", :id => @player.id } %>

in your view, and a corresponding controller action in your PlayerActionsController, or whatever you want to call it

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

This way the actions only happen when the user clicks the link. Of course you will need to handle any redirects or ajax rendering as well, as well as validation, etc. But this is generally how your Rails code should be structured.

暮光沉寂 2024-11-10 07:45:38

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

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

在 CRUD - 创建、检索、更新和删除中,只有检索应该使用 GET 完成,其他则通过 POST 完成。有人说使用 PUTDELETE,但实际上,它是通过使用 _methodPOST 来完成的param 或类似的名称。

请参阅:为什么 Ruby on Rails 书籍或参考文献总是说更新是通过 PUT 进行的,而销毁是通过 DELETE 进行的,而事实并非如此?

You should never use a GET do any change to the server. Some browsers even "pre-fetch" data linked on the page, so it can make changes on the server without the user knowing it.

Always use a POST whenever any change is to be made on the server, and browser will ask the user again whether the request is to be submitted again.

In CRUD - Create, Retrieve, Update, and Delete, only Retrieve should be done used GET, the others are done through POST. There is saying about using PUT and DELETE, but in practice, it is done through a POST using a _method param or a similar name.

See: Why Ruby on Rails books or references always say Update is by PUT and Destroy is by DELETE when it is not?

流殇 2024-11-10 07:45:38

无论您如何继续使用 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 请求。

However you proceed with the HTTP verbs, your code has a concept flaw:

<%= link_to (myproperty_path) do %>
<% @player.update_attribute("energy", @player.energy + 2) %><span>Take a Nap</span>
<%end%>

When you open this page, the @player.update_attributes call will fire once while generating the link. The actual database change has to take place within a controller (in this case the routing target for myproperty_path).

Additionally I totally agree that you should use a POST request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文