Как проверить в Rails 5 разные ActiveRecord для одного и того же действия - PullRequest
0 голосов
/ 07 января 2019

Я создаю систему аутентификации в Rails5, и у меня есть пользователь, для которого я хочу проверить уникальность и правильный формат для поля электронной почты. Я видел, что обе ошибки выдают одно и то же исключение, ActiveRecord :: RecordInvalid, и я хотел бы знать, как я могу управлять обоими случаями хорошим и элегантным способом.

Это было бы важной частью моей модели. Пользователь:

validates_format_of :email, with: URI::MailTo::EMAIL_REGEXP
validates_presence_of :email
validates_uniqueness_of :email

И это будет контроллер:

begin
  user.save!
  render status: :created, json: { msg: 'User was created.' }
rescue ActiveRecord::RecordInvalid => err
  render status: conflict, json: { msg: err }
end

Что я хотел бы сделать, это провести различие между ошибкой уникальности (для возврата 409) и ошибкой форматирования (для возврата 400).

Буду признателен за любые комментарии или помощь о том, как лучше выполнить эту проверку.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Поймать исключение ActiveRecord::RecordInvalid - не лучший способ справиться с этим делом. Вместо этого я бы предложил явно запустить проверку и проверить объект errors.

Проверьте документацию по Rails API для ActiveModel::Validations (https://api.rubyonrails.org/classes/ActiveModel/Validations.html#method-i-errors) и ActiveModel::Errors (https://api.rubyonrails.org/classes/ActiveModel/Errors.html).

)

После запуска user.valid? вы можете исследовать объект user.errors, чтобы определить точный тип ошибки проверки. Затем вы можете ответить с другими кодами ответа, как вы хотите:

if !user.valid?
  if user.errors[:email] == [" ... uniqueness error ..."]
    # return 409
  elsif user.errors[:email] == [" ... format error ..."]
    # return 400
  else
    # ...
  end
else
  user.save!
  # ...
end
0 голосов
/ 07 января 2019

Вместо того, чтобы делать user.save!, обрабатывать user.save

if user.save
  render status: :created, json: { msg: 'User was created.' }
else
  render status: conflict, json: { msg: user.errors.full_messages.join(', ') }
end

версия взрыва (save!) вызывает исключение, если объект не был сохранен по какой-либо причине, тогда как версия без взрыва (save) возвращает true, если объект сохранен, и false, если это не.

Чтобы дополнительно различать тип ошибки проверки, вы можете использовать #added?:

user.errors.added? :email, :taken => true, если ошибка уникальности электронной почты

user.errors.added? :email, :invalid => true, если ошибка форматирования электронной почты.

...