Тестовый пример с enum требует ключа после обновления Rails с v4 до v5 - PullRequest
2 голосов
/ 04 августа 2020

Я в процессе обновления своего приложения Rails с v4 до v5. Когда я запускаю тесты, некоторые из них терпят неудачу, что раньше проходило.

Например,

(перечисление)

enum session_type: {regular: 0, demo: 1, promotional: 2}

(использование)

session = {
          :uuid => SecureRandom.uuid,
          :session_type => 0,
}

post :create, :format => :json, params: { :session => session }

Параметр проходит через params.require(:session).permit(...)

'0' is not a valid session_type
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/enum.rb:137:in `assert_valid_value'
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/attribute.rb:67:in `with_value_from_user'
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/attribute_set.rb:51:in `write_from_user'
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/attribute_methods/write.rb:50:in `write_attribute_with_type_cast'
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/attribute_methods/write.rb:32:in `write_attribute'
/home/anz/.rvm/gems/ruby-2.2.3/gems/activerecord-5.0.0/lib/active_record/attribute_methods/write.rb:20:in `__temp__3756373796f6e6f547970756='

Когда я использую regular вместо 0, он работает. Что происходит?

ОБНОВЛЕНИЕ 1 :

При этом правильно анализируются параметры

@request.env['CONTENT_TYPE'] = 'application/json'
post :create, :format => :json, params: { :session => session }

Я пробовал as: :json, но это не сработало. Интересно, почему это не работает, выглядит лучше, чем добавление @request.env.

post :create, as: :json, params: { :session => session }

ОБНОВЛЕНИЕ 2 : После обновления рельсов с 5.0.0 до 5.0.7.2 работает as: :json.

post :create, as: :json, params: { :session => session }

1 Ответ

2 голосов
/ 04 августа 2020

Внимательно посмотрите на сообщение об ошибке, оно жалуется на '0', а не на 0.

Если вы попытаетесь установить session_type в строку, то оно ожидает 'regular', 'demo' или 'promotional'. Если вы используете номер, он ожидает 0, 1 или 2. Но ActiveRecord недостаточно умен, чтобы попытаться преобразовать строку в число, прежде чем увидеть, передаете ли вы допустимое значение, поэтому он просто видит, что '0' - это то, чего нет в %w[regular demo promotional], и сообщает вам, что вы передаете недопустимое значение.

Итак, либо исправьте клиентов для отправки строк, либо настройте синтаксический анализ аргументов для сопоставления строк с числами примерно так:

def model_params
  permitted = params.require(:session).permit(...)
  if(permitted[:session_type].in?(Model.session_types.values.map(&:to_s))
    permitted[:session_type] = permitted[:session_type].to_i
  end
  permitted
end
...