加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails枚举验证不起作用但引发ArgumentError

发布时间:2020-12-17 02:56:29 所属栏目:百科 来源:网络整理
导读:一个线程创建了 here,但它没有解决我的问题. 我的代码是: course.rb class Course ApplicationRecord COURSE_TYPES = %i( trial limited unlimited ) enum course_type: COURSE_TYPES validates_inclusion_of :course_type,in: COURSE_TYPESend courses_con
一个线程创建了 here,但它没有解决我的问题.

我的代码是:

course.rb

class Course < ApplicationRecord
  COURSE_TYPES = %i( trial limited unlimited )
  enum course_type: COURSE_TYPES
  validates_inclusion_of :course_type,in: COURSE_TYPES
end

courses_controller.rb

class CoursesController < ApiController
  def create
    course = Course.new(course_params) # <-- Exception here
    if course.save # <-- But I expect the process can go here
      render json: course,status: :ok
    else
      render json: {error: 'Failed to create course'},status: :unprocessable_entity
    end
  end

  private    
    def course_params
      params.require(:course).permit(:course_type)
    end
end

我的测试用例:

courses_controller_spec.rb

describe '#create' do
  context 'when invalid course type' do
    let(:params) { { course_type: 'english' } }
    before { post :create,params: { course: params } }

    it 'returns 422' do
      expect(response.status).to eq(422)
    end
  end
end

运行上面的测试用例时,我收到了一个ArgumentError异常,该异常在Rails issues中有所描述

所以我希望如果我将一个无效的course_type设置为enum,它将在验证阶段失败而不是引发异常.

另外,我知道在here的rails中挂钩下真正发生了什么,我不想在分配枚举类型值的每个代码块中手动挽救这种异常!

有什么建议吗?

解决方法

更新以支持.valid?进行幂等验证.

这个解决方案不是很优雅,但它确实有效.

我们在API应用程序中遇到了这个问题.每次需要在任何控制器或动作中使用时,我们都不喜欢挽救此错误的想法.所以我们在模型方面拯救了它,如下所示:

class Course < ApplicationRecord
  validate :course_type_should_be_valid

  def course_type=(value)
    super value
    @course_type_backup = nil
  rescue ArgumentError => exception
    error_message = 'is not a valid course_type'
    if exception.message.include? error_message
      @course_type_backup = value
      self[:course_type] = nil
    else
      raise
    end
  end

  private

  def course_type_should_be_valid
    if @course_type_backup
      self.course_type ||= @course_type_backup
      error_message = 'is not a valid course_type'
      errors.add(:course_type,error_message)
    end
  end
end

可以说,rails-team选择引发ArgumentError而不是验证错误是正确的,因为我们可以完全控制用户可以从单选按钮组中选择哪些选项,或者可以选择选择字段,所以如果程序员发生了要添加一个新的单选按钮,其值为拼写错误,那么最好引发错误,因为它是应用程序错误,而不是用户错误.

但是,对于API,这将不起作用,因为我们不再对将哪些值发送到服务器有任何控制.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读