Rails 因为 class 同名引起的问题如何解决?

xlaok · 2016年04月29日 · 最后由 xlaok 回复于 2016年04月29日 · 2912 次阅读

有一个资源叫 Post,有

ActiveRecord::Post 和 API::Entities::Post 两个同名的 class

因为有一些多态链接的内容,所以需要动态获取 class_name,比如 post comment 都会被收藏(bookmark)

有一个 object 是这样的

> object
> bookmarkable_type: 'Post ' bookmarkable_id: 1

我是这么写的

API::Entities.const_get(object.bookmarkable) 

希望取到的结果是 API::Entities::Post 但是在线上跑的时候,有的时候取到的是错误的 Post(model), 有的时候是正确的 API::Entities::Post 应该是同名引起的问题吧,这种问题如何解决呢?

为什么你的 bookmarkable_type 会只保存 Post 呢?正确的情况下,应该保存的是 API::Entities::Post 才对呀。 这样的话,你可以直接通过 bookmark.bookmarkable 方法拿到多态关联的对象。

#1 楼 @lgn21st rails 默认存的就是 Post , bookmark.bookmarkable 也能正确的拿到多态关联的对象 API::Entities::Post 是 grape-entity gem 里用来格式化 json 用的 问题是我用 API::Entities.const_get(object.bookmarkable_type) 有的时候取到 Post,有的时候是 API::Entities::Post 好奇怪。

Auto reload 导致?

是不是直接在 Entities 里面写方法了?

#const_get 这个方法本来就不保证命名空间,如果你内存里已经有一个 Post 而没有 API::Entities::Post 的话,#const_get 就不会走 rails 的 auto load, 直接把你内存里的 Post 给取出来了. 如果想保证命名空间的话,最好还是拼字符串 "::API::Entities::#{...}", 然后调用 ActiveSupport 里的 String#constantize 查了一下文档 Module#const_get, 方法接受两个参数,第一个参数是名字,第二个参数是个布尔值,为 false 的时候就只会在当前 Module 中查询常量,否则会一路在祖先中找下去。

#5 楼 @karloku 赞,两种方法都可以

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