rails - как изменить значения базы данных с помощью ссылки - PullRequest
1 голос
/ 25 апреля 2011

Я делаю сайт, используя рельсы, и мне крайне нужна помощь, как создать ссылку, которая при нажатии на нее обновит атрибут в базе данных, но только при нажатии. У меня есть этот код:

<%= 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. Я нигде не нашел решения, я был бы очень признателен, если бы кто-нибудь помог мне с этим.

Ответы [ 3 ]

8 голосов
/ 26 апреля 2011

Вы делаете это в корне неверно. 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.

2 голосов
/ 25 апреля 2011

Вы никогда не должны использовать GET для каких-либо изменений на сервере. Некоторые браузеры даже «предварительно извлекают» данные, связанные на странице, поэтому они могут вносить изменения на сервере без ведома пользователя.

Всегда используйте POST всякий раз, когда на сервере должно быть сделано какое-либо изменение, и браузер снова спросит пользователя, должен ли запрос быть отправлен снова.

В CRUD - создание, извлечение, обновление и удаление следует использовать только извлечение, используя GET, остальные - через POST. Говорят об использовании PUT и DELETE, но на практике это делается через POST с использованием параметра _method или аналогичного имени.

См .: Почему в книгах или справочниках по Ruby on Rails всегда говорится, что обновление выполняется по PUT, а уничтожение - по DELETE, когда это не так?

0 голосов
/ 26 апреля 2011

Как бы вы ни работали с глаголами 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.

...