V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
final0pro

rails 小白问题

  •  
  •   final0pro · Dec 9, 2015 · 4732 views
    This topic created in 3800 days ago, the information mentioned may be changed or developed.

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

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

    所以如果 id 是空的话,快速报错会比较合适
    cxbig
        12
    cxbig  
       Dec 9, 2015
    @final0pro 通常来说, model 里定义的 validation 是在和数据库交互前就完成的。
    但是跟主键 ID 相关的,比方说 model.new 的時候你給了一個已有的 ID ,那這個錯誤反饋就是來自於數據庫。
    lightening
        13
    lightening  
       Dec 9, 2015
    @final0pro 你可以预先用 user.valid? 方法验证一下是不是能过 validation 。
    final0pro
        14
    final0pro  
    OP
       Dec 9, 2015
    @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
        15
    lightening  
       Dec 9, 2015 via iPhone
    那就没什么办法咯 只好用 strong params 处理一下,或者写个方法简单的过一下 params 。

    当然你也可以先 valid?一下然后看 user.errors 里除去 blah 的 attributes 有没有报错。
    crayygy
        16
    crayygy  
       Dec 9, 2015
    之前想学 RoR 来着,看了段时间就疲了,没有耐心坚持下去...
    final0pro
        17
    final0pro  
    OP
       Dec 9, 2015
    @lightening 哈哈哈。还是开始来的直接!以前写 java 写的习惯了。。。
    final0pro
        18
    final0pro  
    OP
       Dec 9, 2015
    @crayygy project 就是源动力
    jimrok
        19
    jimrok  
       Dec 9, 2015
    我可以建议你用 grape 来做吗?
    TangMonk
        20
    TangMonk  
       Dec 9, 2015
    grape
    crayygy
        21
    crayygy  
       Dec 9, 2015
    @final0pro 然而我都是自学,基本上没有什么 ddl 的压力,所以就三分钟热度了,过几天就不想学了,我也是很烦躁...
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2827 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 03:46 · PVG 11:46 · LAX 20:46 · JFK 23:46
    ♥ Do have faith in what you're doing.