首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Ruby on Rails

rails 小白问题

  •  
  •   final0pro · 2015-12-09 00:25:40 +08:00 · 2519 次点击
    这是一个创建于 1463 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚接触 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)

    我错了...

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

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

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

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

    当然你也可以先 valid?一下然后看 user.errors 里除去 blah 的 attributes 有没有报错。
        16
    crayygy   2015-12-09 08:59:37 +08:00
    之前想学 RoR 来着,看了段时间就疲了,没有耐心坚持下去...
        17
    final0pro   2015-12-09 13:13:13 +08:00
    @lightening 哈哈哈。还是开始来的直接!以前写 java 写的习惯了。。。
        18
    final0pro   2015-12-09 13:13:28 +08:00
    @crayygy project 就是源动力
        19
    jimrok   2015-12-09 13:16:06 +08:00
    我可以建议你用 grape 来做吗?
        20
    TangMonk   2015-12-09 13:43:43 +08:00
    grape
        21
    crayygy   2015-12-09 17:42:19 +08:00
    @final0pro 然而我都是自学,基本上没有什么 ddl 的压力,所以就三分钟热度了,过几天就不想学了,我也是很烦躁...
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1441 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 17:13 · PVG 01:13 · LAX 09:13 · JFK 12:13
    ♥ Do have faith in what you're doing.