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 here
The 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.
However you proceed with the HTTP verbs, your code has a concept flaw:
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.
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 throughPOST
. There is saying about usingPUT
andDELETE
, but in practice, it is done through aPOST
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?
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
in your view, and a corresponding controller action in your PlayerActionsController, or whatever you want to call it
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.