Rails 求 grape-entity 使用经验分享

42thcoder · 发布于 2014年11月03日 · 最后由 iBachue 回复于 2014年11月06日 · 2616 次阅读
6764

目前做得项目重度使用了 grape-entity, 一边看wiki, 一边翻源码, 写得倒也顺利. 但是始终有几个问题解决不好, 还请论坛里的高手, 分享下自己的经验, 谢谢~

主要的问题:

  • 多个entity放在同一个文件里, 会出现 NameError
  • 代码中出现 bug, 服务器( thin )假死, 只能 kill + 重启.
  • 不同版本的 API 如何共享 entity
  • 使用 Grape::Entity::DSL 直接在 model 中定义 entity. 这样做, 好不好
共收到 13 条回复
6764

#1楼 @iBachue

频繁报 NameError (uninitialized constant V1::App::Entity::User) 这样的错误.

entity.rb 里面定义了

module V1
  module App
    module Entity

      # 用户
      class User < Grape::Entity
        expose :id, :nick, :avatar
      end

    end
end
172

#2楼 @42thcoder 你能把发生错误的代码贴出嘛?

6764

#3楼 @iBachue 谢谢回复~

endpoint 定义在 users.rb 文件中, 大致的逻辑是这样的:

require_relative "entity"

module V1
  module App
    class Works < Grape::API
      user = User.first

      present user, with: Entity::User
    end
  end
end

entity.rb 文件中定义了许多 entity, 大概像这样:

module V1
  module App
    module Entity
      # 商家
      class MerchantSummary < Grape::Entity
        expose :id, :name, :address, :logo_path
      end

      class Merchant < MerchantSummary
        expose :rating
      end


      # 用户
      class UserSummary < Grape::Entity
        expose :id, :nick, :avatar
      end

      class User < UserSummary
        expose :created_at
      end

    end
  end
end
172

#4楼 @42thcoder 抱歉 凭肉眼没能看出错误的根源,能够贴下backtrace 就是堆栈信息?

6764

#5楼 @iBachue

NameError (uninitialized constant V1::App::Entity::User):
  /Users/hackerZhang/work/app/api/v1/app/works.rb:32:in `block (2 levels) in <class:Works>'
  /Users/hackerZhang/.rvm/gems/ruby-2.1.2@rails4.0.2/gems/grape-0.9.0/lib/grape/endpoint.rb:45:in `call'
  /Users/hackerZhang/.rvm/gems/ruby-2.1.2@rails4.0.2/gems/grape-0.9.0/lib/grape/endpoint.rb:45:in `block in generate_api_method'
  # 剩下的删掉了, 基本上没啥用
172

#6楼 @42thcoder 你的出错点在 /Users/hackerZhang/work/app/api/v1/app/works.rb 第32行嘛 你把那个文件贴上来 应该就可以发现问题了。。

6764

#7楼 @iBachue

32行就是下面代码中的 present user, with: Entity::User

require_relative "entity"

module V1
  module App
    class Works < Grape::API
      user = User.first

      present user, with: Entity::User
    end
  end
end
172

#8楼 @42thcoder 在这种情况下,你尝试下替换成 ::V1::App::Entity::User 是不是就对了,如果对的话,就逐一削减搜索条件直到错误为止。 蛮奇怪的,我本地试类似代码都没有问题。

6764

#9楼 @iBachue 也是不行的, 我在 rails console 中做过各种实验, 打印 V1::App::Entity.constants V1::App::Entity::User 之类的, 有时可以找到, 有时候找不到, 十分神奇.

百思不得其解, 整个人都不好了

我现在把代码写到models/user.rb中, 就可以了, 类似这样:

class User < ActiveRecord::Base
  include Grape::Entity::DSL

  entity :id, :nick, :avatar do
    root 'authors', 'author'
  end
end
172

#10楼 @42thcoder 其实写 Ruby 你不用思考这么多 不用瞎猜 也不用整个人都不好 直接 Debug 就可以。

require_relative "entity"

module V1
  module App
    class Works < Grape::API
      user = User.first
require 'pry'; binding.pry unless defined?(::V1::App::Entity::User)
      present user, with: Entity::User
    end
  end
end

pry-byebug,只要代码在断点处停下 就可以通过研究那一刻的 $LOADED_FEATURES,来看那个文件是否已经加载。如果没加载,研究为什么之前的require_relative没有出错,它到底加载了那个文件,这样就可以了。

6764

@iBachue pry 真是神器, 谢谢~

文件已经加载了, 但没找到类.

[25] pry(V1::App::Entity):3> $LOADED_FEATURES.select{|file| file.include? 'entity' }
=> ["/Users/hackerZhang/.rvm/gems/ruby-2.1.2@rails4.0.2/gems/pry-0.10.1/lib/pry/commands/ls/ls_entity.rb",
 "/Users/hackerZhang/work/app/api/v1/app/entity.rb"]
[26] pry(V1::App::Entity):3> ls
constants:  Product
locals: _  __  _dir_  _ex_  _file_  _in_  _out_  _pry_

/Users/hackerZhang/work/app/api/v1/app/entity.rb 这个文件是对的. 找到那个类Product, 是在API文件products.rb中直接定义的.

13楼 已删除
172

#12楼 @42thcoder 那就更加神奇了 一个文件被加载过 定义的类却不见了 你可以尝试再次加载 看看有没有出现,如果出现就表示之前哪里把定义的类删掉了。如果没有出现,你检查是不是代码里有错别字神马的。。。

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