Передача переменной между функцией контроллера в рельсах

Я изучаю рельсы (и Ruby) и хотел бы знать, можно ли передавать переменную между функциями контроллера.

По сути, мою проблему можно было бы возобновить следующим образом:

#controller.rb

def pageA
    #assuming @variable is from a form
    @variable = "foo"

    if @variable == "foo"
        redirect_to action: 'pageB'
    else
        ...
    end

end

def pageB
    #I'd like to reuse @variable in pageB.html.erb
end

Возможно ли использовать redirect_to ? Должен ли я использовать другой подход?

Из любопытства, можно ли решить эту проблему с помощью кеша?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это невозможно, как вы пытаетесь сделать. Ruby on Rails, как и многие другие серверные веб-фреймворки, по сути, начинает заново обрабатывать состояние для каждого запроса.

Это означает: пользователь что-то запрашивает (например, вызывает страницу A), и при запросе другой страницы (например, страницы B) состояние не сохраняется. Когда вы перенаправляете пользователя, Rails отправляет обратно команду перенаправления в браузер, а затем начинается новый запрос к серверу Rails.

Если вы хотите сохранить состояние или другие данные, вам необходимо закодировать их в URL-адресе (или использовать сеансы, например, если у вас есть система входа в систему).

В вашем случае вы можете просто добавить @variable, полученную из формы (т. е. массива params), в перенаправление:

redirect_to action: 'pageB', variable: @variable

Тогда в методе pageB старое значение переменной снова будет доступно как params[:variable]. Значение появится в URL-адресе.

Имейте в виду, что вам не следует кодировать конфиденциальные данные, такие как пароли, с помощью этого метода.

Дополнительные примеры использования метода redirect_to можно увидеть в документации Rails

В зависимости от содержимого страницы «pageB» и от того, выполняет ли действие контроллера что-то конкретное, простой render :pageB также может сработать.

engineersmnky 28.06.2024 20:50
Ответ принят как подходящий

Вы думаете об этом на слишком низком уровне.

Переменные — это всего лишь инструмент, который вы используете для указания данных в памяти при обработке запроса, и они не сохраняются надежно между одним запросом к другому. Они никогда не являются действительной частью конечной цели.

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

Скорее вам нужно думать об этом с точки зрения передачи состояния (или ссылок на него) туда и обратно между сервером и клиентом. HTTP предоставляет для этого несколько механизмов, таких как URI, тело запроса и заголовки.

Данные, которые необходимо сохранять между запросами на сервере, необходимо хранить где-то, например в базе данных. В этом случае нам не нужно передавать фактические данные. Нам просто нужно сообщить серверу, что мы ищем.

В типичном случае настройки REST Rails (в виде ресурсов) сохраняются в базе данных, а затем вы просто перенаправляетесь на этот ресурс.

class ThingController < ApplicationController
  # Displays a form to create a new resource
  # GET /things/new
  def new
    @thing = Things.new
  end

  # Responds to form submissions
  # POST /things
  def create
    @thing = Thing.new(thing_params)
    if @thing.save
      redirect_to @thing # redirect to /things/:id
    else
      render :new        # renders the form again
    end
  end

  # Shows a member of the collection
  # GET /things/1
  def show
    @thing = Thing.find(params[:id])
  end

  private

  def thing_params
    params.require(:thing)
          .permit(:foo, :bar)
  end
end

Здесь мы просто передаем идентификатор записи как часть URL-адреса и можем использовать его в следующем запросе для получения вновь созданной записи.

Обратите внимание, что типичная ловушка для новичков в Rails — это попытка использовать перенаправление для «неудавшейся» отправки формы:

def create
  @thing = Thing.new(thing_params)
  @my_var= 'Hello World'

  if @thing.save
    redirect_to @thing, my_param: @my_var # redirect to /things/:id
  else
    redirect_to action: :new              # OMG How do I pass all the data along?
  end
end

Если пользователь пытается создать/обновить ресурс с недопустимыми данными, просто отобразите форму еще раз и вместо этого отправьте ее в качестве ответа.

Если вам действительно необходимо передать дополнительные данные с сервера вместе с перенаправлением, вы можете использовать параметры строки запроса:

# Responds to form submissions
# POST /things
def create
  @thing = Things.new(thing_params)
  @my_var = 'Hello World'
  if @thing.save
    redirect_to @thing, my_param: @my_var # redirect to /things/:id
  else
    render :new                           # renders the form again
  end
end

# Shows a member of the collection
# GET /things/1
def show
  @my_var = params[:my_param]
  @thing = Thing.find(params[:id])
end

Любые дополнительные параметры, переданные в redirect_to (за исключением именованных параметров, таких как status, notice, alert), будут добавлены к URL-адресу в качестве параметров строки запроса. Хотя, безусловно, существуют действительные варианты использования, спросите себя, действительно ли вам это нужно, и примите во внимание безопасность.

Если вам нужен более прозрачный механизм передачи состояния браузеру и его отправки обратно, можно использовать файлы cookie . Rails предоставляет механизм сеансов, который можно использовать для хранения данных в файлах cookie на более высоком уровне.

Из любопытства, можно ли решить эту проблему с помощью кеша?

Не совсем.

Кэш — это способ повысить производительность за счет хранения данных, производство которых требует больших затрат. Любой кэш, специфичный для пользователя, по-прежнему нуждается в механизме идентификации пользователя.

Другие вопросы по теме