#ruby-on-rails #model #controller #instance #increment
#ruby-on-rails #Модель #контроллер #экземпляр #увеличить
Вопрос:
Я пытался сохранить переменную экземпляра, а затем увеличить значение для этой переменной экземпляра, но она всегда сбрасывается при перезагрузке.
Модель выглядит следующим образом
class Waiting < ApplicationRecord
def increment
self.number_waiting = 1
save!
end
def decrement
self.number_waiting -= 1
save!
end
def reset
self.number_waiting = 0
save!
end
end
Контроллер выглядит следующим образом
class IndexController < ApplicationController
def index
@waiting ||= Waiting.new(number_waiting: 0)
@waiting.increment
@waiting.save!
end
end
Html выглядит следующим образом:
<p id="waiting_counter">
<% @waiting.increment %>
<%= @waiting.number_waiting %>
<% @waiting.save! %>
</p>
По какой-то причине она всегда равна 2 и никогда не меняется… Несколько часов искал решение этой простой проблемы, пожалуйста, помогите.
Комментарии:
1. Можете ли вы дать описание того, какую проблему должен решать этот код? «Когда пользователь нажимает … тогда они должны видеть… и затем …»
2. Например, это что-то вроде автоматической системы запросов?
Ответ №1:
Пошаговое руководство по вашему коду, и должно быть очевидно, почему оно всегда равно 2.
Я предполагаю, что вы переходите к IndexController#index
(вероятно, через indexes_path). Это создает совершенно новый ожидающий объект, инициализированный значением 0, который в следующей строке увеличивается на 1. Затем вы сохраняете ее.
Затем (предполагая, что html взят из index.html.erb) rails отобразит html, во время которого объект @waiting увеличивается еще раз, перед отображением значения, которое теперь равно 2. Затем этот объект снова сохраняется.
Она ведет себя точно так, как должна, однако я думаю, что реальная проблема заключается в том, что у вас может быть неправильное представление о том, как работает rails. При вызове индексного действия на контроллере результатом вызова этого действия (по умолчанию) является то, что страница index.html.erb будет отображаться, в течение которого оценивается встроенный ruby. Все это происходит на стороне сервера, а затем результирующий HTML отправляется обратно клиенту. У вас нет ничего на стороне клиента, чтобы инициировать запуск приращения.
Неясно, чего вы на самом деле пытаетесь достичь здесь, и каким образом ожидается вызов приращения.
После рассмотрения вашего вопроса мне пришло в голову, что, возможно, вы ожидаете, что переменная экземпляра будет доступна для всех запросов после инициализации. Это не так — каждый запрос будет получать новый экземпляр контроллера, поэтому при каждой перезагрузке page @instance изначально будет равен нулю и приведет к созданию нового ожидающего объекта. Вместо этого вам следует захватить ожидающий объект из базы данных и затем увеличить его, например:
def index
@waiting = Waiting.first
@waiting ||= Waiting.new(number_waiting: 0)
@waiting.increment
@waiting.save!
end
Кстати, по соглашению вы обычно отображаете список существующих объектов с помощью действия index.
Комментарии:
1. Большое спасибо за ваш пространный ответ, вы решили мою проблему. 🙂
2. рад, что смог помочь 🙂 если это действительно решит ваш вопрос, было бы здорово, если бы вы могли принять решение 🙂