rails 小白问题

2015-12-09 00:25:40 +08:00
 final0pro

刚接触 rails4 不久,在写一个 API

对一个请求,我想验证传进来的
URL 参数是否合法,要求一个参数 id 必须非空。

google 了下,最佳实践是在 model 层里添加 validation 。

有点不解。

比方说,在 controller 里

user = User.new(params)
# 做些其他 耗时的操作
user.save!

id 的 validation 发生在 user.save!,这样就算是 null ,那些耗时的操作仍然会发生。

validation 不应该是接受请求之后第一件做的事情吗?

不知道用 Strong Parameters 是否能解决这个问题

JOSN body 大致这样

{
  "request": {
    "id": "1"
  }
}

params.require(:request)这样可以确保:request 存在,但是没找到例子可以确保 id 存在?


好吧,好像 require 可以用多次

这样
params.require(:request).require(:id)

我错了...

3969 次点击
所在节点    Ruby on Rails
21 条回复
chaucerling
2015-12-09 00:52:07 +08:00
如果有 api 参数验证的场景,试试 grape
写了差不多一年 rails , 我觉得它不太适合做 api ,而是快速开发表单和内容展示为主的网站
cuebyte
2015-12-09 01:51:00 +08:00
require 后面可以加 permit
cxbig
2015-12-09 02:50:38 +08:00
根据 ror 的定义,任何跟 model 有关的东西都是交由 model 来处理的
controller 只负责 filter 掉非正常的参数。
pynix
2015-12-09 03:11:21 +08:00
耗时操作必须是同步的=
pynix
2015-12-09 03:11:41 +08:00
吗?
lightening
2015-12-09 03:39:45 +08:00
最好把耗时的操作改成异步……
不过,你也可以
```
user = User.new(user_params)

if user.valid?
do_something
user.save
end
```
final0pro
2015-12-09 03:52:49 +08:00
@chaucerling 哈哈,这个不是我能决定的
final0pro
2015-12-09 03:53:06 +08:00
@chaucerling 我也同意你。 rails 挺适合个人开发
final0pro
2015-12-09 03:53:28 +08:00
@cuebyte permit 只是允许某些参数可以接受,但不是强制的
final0pro
2015-12-09 03:54:53 +08:00
@cxbig 但是 rails4 新增的 strong parameters 特性好像就可以先 validate 一下。 model 的 validation 只能在提交到数据库才会执行,不会发生在`user.new(params)`吧?
final0pro
2015-12-09 03:56:47 +08:00
@pynix @lightening 我简略写了。其实是创建 user (user.new)里面,在提交到数据库之前,要跟很多第三方服务交流。

所以如果 id 是空的话,快速报错会比较合适
cxbig
2015-12-09 05:21:01 +08:00
@final0pro 通常来说, model 里定义的 validation 是在和数据库交互前就完成的。
但是跟主键 ID 相关的,比方说 model.new 的時候你給了一個已有的 ID ,那這個錯誤反饋就是來自於數據庫。
lightening
2015-12-09 05:41:34 +08:00
@final0pro 你可以预先用 user.valid? 方法验证一下是不是能过 validation 。
final0pro
2015-12-09 05:51:44 +08:00
@lightening 比如说 User 还有个 blah field ,这个 blah 非空,但是这个 blah 要通过第三方服务来获得。

在 User.initialize(params) 中

def initialize(params)
user = User.new(params)
# 无法调用 valid?,因为 blah 此时为 nil ,肯定 return false
# 而且 third_party 需要 params 里的 :lala ,还需要确保在获取 request parameters 的时候 lala 在里面
user.blah = third_party.get_blah(params[:lala])
user
end

:(
lightening
2015-12-09 08:19:38 +08:00
那就没什么办法咯 只好用 strong params 处理一下,或者写个方法简单的过一下 params 。

当然你也可以先 valid?一下然后看 user.errors 里除去 blah 的 attributes 有没有报错。
crayygy
2015-12-09 08:59:37 +08:00
之前想学 RoR 来着,看了段时间就疲了,没有耐心坚持下去...
final0pro
2015-12-09 13:13:13 +08:00
@lightening 哈哈哈。还是开始来的直接!以前写 java 写的习惯了。。。
final0pro
2015-12-09 13:13:28 +08:00
@crayygy project 就是源动力
jimrok
2015-12-09 13:16:06 +08:00
我可以建议你用 grape 来做吗?
TangMonk
2015-12-09 13:43:43 +08:00
grape

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/242136

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX