Переменная экземпляра контроллера Ruby on Rails не является общей - PullRequest
0 голосов
/ 13 сентября 2018

Мое новое действие генерирует объект корзины @cart из сеанса. Когда я вызываю действие «обновление» через AJAX, объект @cart не существует. Почему он не используется в контроллере?

cart_controller.rb

def new
  @cart = Cart.new(session[:cart])
end

def update
  logger.debug @cart.present? # false
end

Ответы [ 5 ]

0 голосов
/ 14 сентября 2018

Я бы предложил использовать before_action для создания экземпляра @cart, в случае, если переменная экземпляра @cart будет видима для new и update действий.

before_action :get_cart, only: [:new, :update]

private
def get_cart
  @cart = Cart.new(session[:cart])
end 

Если вы не хотите использовать обратные вызовы действий, другой альтернативой является прямой вызов метода get_cart для действий new и update.Так как get_cart возвращает экземпляр @cart.Как ссылка на это вы можете увидеть эту ссылку

0 голосов
/ 13 сентября 2018

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

Концептуально то, что вы ожидаете, должно быть правильным!Вы определяете переменную экземпляра, и у вас должен быть доступ к ней везде по всему классу.

Проблема в том, что при каждом HTTP-запросе создается новый экземпляр класса.

Итаккогда вы нажимаете действие new, запускается экземпляр контроллера, вызывается метод new и создается и назначается @cart.Что-то вроде:

# HTTP request /new
controller = MyController.new # an object of your controller is created
controller.new # the requested action is called and @cart is assigned

Но когда вы делаете новый HTTP-запрос к update, будет инициирован новый экземпляр контроллера, будет вызван метод update, и у него нет @cart!

# HTTP request /update
controller1 = MyController.new # an object of your controller is created
controller1.new # the requested action is called and @cart is not assigned ?

Как видите, controller и controller1 - это два разных объекта, инициированных из MyController, как это происходило в двух разных HTTP-запросах (в разных контекстах).

ИсправитьВаш вопрос вам нужно создать @cart для каждого действия, когда нужно что-то вроде:

def new
  cart
end

def update
  logger.debug cart.present?
end

private

def cart
  @cart ||= Cart.new(session[:cart])
end
0 голосов
/ 13 сентября 2018

Переменные экземпляра не могут совместно использоваться контроллером.Они доступны для actions, где они определены.Таким образом, вы не можете использовать @cart в update действии, поскольку вы его не определили.

def new
  @cart = Cart.new(session[:cart])
end

def update
  @cart = Cart.new(session[:cart])
  logger.debug @cart.present?
end

Для DRY кода, используйте before_action для установки корзины

before_action :set_cart, only: [:new, :update]

def new
end

def update
  logger.debug @cart.present?
end

private
def set_cart
  @cart = Cart.new(session[:cart])
end
0 голосов
/ 13 сентября 2018

@cart - переменная экземпляра, и она не сохраняется между запросами.И session доступен между запросами.

В основном, если вы установили некоторые данные в сеанс, вы можете использовать эти данные между запросами.Как уже упоминалось, вы можете настроить before_filter и предварительно установить @cart переменную экземпляра перед выполнением действия update.

class MyController < ApplicationController
  before_action :instantiate_cart, only: [:update] #is the list of actions you want to affect with this `before_action` method
  ...
  private

  def instantiate_cart
    @cart = Cart.new(session[:cart])
  end
end
0 голосов
/ 13 сентября 2018

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

def new
  cart
end

def update
  logger.debug cart.present?
end

private

def cart
  @cart ||= Cart.new(session[:cart])
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...