新手问题 求问 create! 报错和 rescue 之间的关系

smartepsh · 2016年10月12日 · 最后由 smartepsh 回复于 2016年10月14日 · 1747 次阅读

前提条件:

  1. 数据库有一个字段在迁移里设置的为 not null
  2. 该字段并没有在 model 里进行非空约束

代码

def create
  begin
    @model = Model.create!(params)
    render json: @model, status: 201
  resuce
    render head: :forbidden
  end
end 

其中 params 未包含不为空的那个字段

猜想

由于与不为空冲突,所以报错会被捕捉并 render forbidden

现实

  1. 200 OK……(创建成功应该是 201 created)
  2. 数据没有成功保存
  3. 不处理异常去掉 begin/end/rescue 的话,会报错

疑问

  1. 为什么不会按照猜想走,为什么不会报错?
  2. 为什么渲染了 200 OK……?
  3. 应该怎么做?(除了在 model 里设置不为空外)
  4. 一般开发,是应该是数据库做非空约束,还是在 model 层做约束,还是两者都做?

我知道 model 层的非空不会给数据库做非空约束

那个 @model 有没有被创建出来存进数据库?

#1 楼 @blacktulip 我问的就是存的过程为什么没报错呀,毕竟 create 么。😅

我更喜欢在 model 做 validate

#3 楼 @jicheng1014 嗯嗯,是要做的,我也是先写了控制器,没写 model 约束,才发现的这个问题

#2 楼 @smartepsh 那存进去的那个 record 在你说那个字段的 value 是啥呢?

#5 楼 @blacktulip 没 value,就是我明知道那个不可为空的字段是空的,按理应该报错,但是他不报……

#6 楼 @smartepsh 那就是说你的数据库非空约束没起作用咯?你是怎么做的非空约束?有没有漏了 db:migrate 之类的?

#7 楼 @blacktulip 其实是报错了,如果把代码不用 begin 和 end 包裹,不处理异常,就会报错。但是按我上面的写法,就不报错

#7 楼 @blacktulip 约束等于是做在数据库里面了

#7 楼 @blacktulip 不好意思,让你误解了,内容我稍微改了下。

是不是你控制器健壮参数的原因导致数据没有保存

#11 楼 @seven.lee 不是,我没有使用健壮参数。是因为数据库本身的非空约束,导致记录无法存储,但是 model 层没做约束,所以 model 层是通过的。现在的主要问题就是:为什么 rescue 没有捕获到这个没有存入的报错信息(应该由数据库 gem 报错)

为什么不会按照猜想走,为什么不会报错?

因为 resuce 截获了异常

为什么渲染了200 OK……?

如果是 403 应该这么写 render status: :forbidden

#13 楼 @jpman render head 是新方法,没有问题的。render head: :forbidden, status: 403

#14 楼 @smartepsh render status: 403 等于 render status: :forbidden 至于render head: :forbidden 我特意用了 rails 5 试了一下就是 返回 200

#15 楼 @jpman 😘 我也试了一下……确实是……不过 render head 之前我一直在用,都是会按照 status 的值返回报头的……这个不知道为什么🚶

需要 登录 后方可回复, 如果你还没有账号请 注册新账号