Передача переменной Rails в метод контроллера

Итак, у меня есть программа, над которой я некоторое время работал, это просто базовая система сканирования штрих-кода.

Мой контроллер для необработанного товара выглядит следующим образом:

class RawsController < ApplicationController
  def new
        @raw = Raw.new
  end

        def create
        @raw = Raw.new(params[raw_params])
        if @raw.save
            receive(@raw)
            redirect_to new_raw_path
        end     
    end

  def receive(raw)
        scanned = Raw.find_by(code: raw.code)
        if scanned.quantity.nil?
            flash[:danger] = "no match"
        else
            scanned.quantity += 1
            if scanned.save
                respond_to do |format|
                    format.html {}
                    format.json{}
                end
            end
        end
  end
private
    def raw_params
        params.require(:raw).permit(:code, :product, :quantity)
    end

end

Теперь я хочу, чтобы когда кто-то вводит номер штрих-кода в форму, он создавал @raw как экземпляр класса Raw (для сырых товаров). Затем в функции получения он ищет соответствующий продукт в моем инвентаре, а затем добавляет одну единицу в мой инвентарь сырья.

Однако, как только я доберусь до строки scanned.quantity += 1, я постоянно получаю сообщение об ошибке, что этот метод не определен для класса nil.

Я добавил в строку scanned.quantity.nil?, и я получаю это быстрое сообщение, поэтому я знаю, что проблема связана с тем, что количество равно нулю. Но я не уверен, как это исправить.

Любая помощь?


person Mascasc    schedule 26.07.2016    source источник
comment
Как вы получаете получение в случае, если scanned равно нулю?   -  person j-dexx    schedule 26.07.2016
comment
Дело не в том, что quantity это nil, а scanned это nil. Чтобы помочь вам лучше понять сообщение об ошибке, quantity — это метод, к которому вы пытаетесь получить доступ из scanned, который равен nil.   -  person sjagr    schedule 26.07.2016


Ответы (3)


Проблема с вашей инициализацией в Raw.new(...)

Глядя на данные, которые вы разместили в этом comment, я мог бы сказать, что действие не создает объект Raw с правильными атрибутами. Вам нужно использовать разрешенные атрибуты, когда вы хотите сохранить. Вы звоните new с params[raw_params], который будет nil. Должно быть Raw.new(raw_params)

Изменять:

  def create
    @raw = Raw.new(raw_params)
    if @raw.save
        receive(@raw)
        redirect_to new_raw_path
    end
  end
person aBadAssCowboy    schedule 26.07.2016
comment
Да! Большое спасибо. Я изначально разработал эту программу, не понимая, что мне нужно будет учитывать сильные параметры. Простая проблема, вызванная плохим синтаксисом. Никогда бы не понял этого. Еще раз спасибо. - person Mascasc; 26.07.2016

Поскольку ваше предложение if с scanned.quantity.nil? выполнено успешно, это означает, что объект scanned присутствует, однако quantity является nil. Я предполагаю, что у вас не было значения по умолчанию 0.

В идеале я бы добавил значение по умолчанию 0 в столбец quantity в ходе миграции, которая добавила этот столбец в базу данных.

Однако вы можете установить его на 0 перед выполнением приращения. Кроме того, вам действительно не нужно делать find_by снова, так как вы уже передаете объект Raw. Действия могут выполняться над самим объектом.

def receive(raw)
    scanned = raw

    if scanned.nil?
      # your flash message
    else
      scanned.quantity ||= 0
      scanned.quantity += 1
      if scanned.save
         respond_to do |format|
             format.html {}
             format.json{}
         end
       end
     end
end
person aBadAssCowboy    schedule 26.07.2016
comment
Меня смущает то, что я добавил некоторые тестовые переменные в миграцию, поэтому количество не равно нулю. - person Mascasc; 26.07.2016
comment
можно вставить результат puts @raw.attributes перед вызовом receive(@raw) ? - person aBadAssCowboy; 26.07.2016
comment
Кроме того, вам не нужно делать find_by в методе receive, поскольку вы уже передаете объект, который вы извлекаете. Я обновил свой ответ, чтобы отразить это. - person aBadAssCowboy; 26.07.2016
comment
Путы: {id=›538, code=›nil, product=›nil,quantity=›nil, created_at=›Tue, 26 Jul 2016 14:26:06 UTC +00:00, updated_at=›Tue, 26 Jul 2016 14:26:06 UTC +00:00} - person Mascasc; 26.07.2016
comment
@Mascasc Вы совершенно не туда смотрите! Смотрите мой новый ответ. - person aBadAssCowboy; 26.07.2016

Вы пытаетесь += со значением nil, поэтому вы получаете эту ошибку.

Когда вы создаете новый экземпляр @raw, значение @raw.quantity равно nil

Используйте after_initialize, чтобы установить количество на 0

class Raw
  after_initialize :set_quantity

  def set_quantity
    self.quantity = 0
  end
end

Или

Напишите миграцию, чтобы изменить значение количества по умолчанию на 0

def change
  change_column :raw, :quantity, :integer, default: 0
end
person Deepak Mahakale    schedule 26.07.2016
comment
Я все еще не получаю совпадений, что, я думаю, означает, что моя отсканированная переменная не найдена. - person Mascasc; 26.07.2016
comment
Насколько я думаю, это не может быть nil. Вы сохраняете @raw, а затем передаете его, и вы find_by на Raw с тем же code. Он должен присутствовать. - person aBadAssCowboy; 26.07.2016
comment
понял, ваше количество равно нулю - person Deepak Mahakale; 26.07.2016
comment
Обновил мой ответ в соответствии с вашим сценарием - person Deepak Mahakale; 26.07.2016