Rails API版本控制命名空间问题

时间:2014-08-04 15:45:37

标签: ruby-on-rails ruby api serializer

我正在接管一个遗留的rails项目,我在使用API​​版本控制的命名空间时遇到了问题。

在前一个开发人员的带领下,控制器和序列化程序按版本化目录进行组织,如下所示:

/controllers
    /api
        /v1
            ...api v1 controllers here
        /v2
            ...api v2 controllers here
/serializers
    /v1
        ...api v1 serializers here
    /v2
        ...api v2 serializers here

然后在.rb文件中,看起来通过与该文件夹结构匹配的命名空间访问各种组件。例如:

class Api::V1::PostsController < ApplicationController

    def index
         @moves = Posts.all()
         render json: @moves, each_serializer ::V1::PostSerializer

一切都很好。问题是,如果我想从V1内部从V2命名空间访问某些东西,我会收到错误。例如,如果我想做这样的事情:

class Api::V1::PostsController < ApplicationController

    def comments
         @comments = Comments.where(:post_id => params[:id])
         render json: @comments, each_serializer ::V2::CommentSerializer

我收到此错误:

SyntaxError (
    /path/to/ptoject/app/controllers/api/v1/posts_controller.rb:22: syntax error,
    unexpected tLABEL
    render json: @comments, each_serializer: ::V2:CommentSerializer
                                               ^):

那么从V1调用V2命名空间需要做什么呢?

2 个答案:

答案 0 :(得分:0)

您的问题是您正在尝试访问命名空间的序列化程序。

您不应该从V1模块访问V2 :: CommentSerializer。

相反,你应该创建一个专为API :: V1

设计的V1 :: CommentSerializer

答案 1 :(得分:0)

我遇到了同样的问题,我认为通过对API进行版本控制并在V1控制器版本中调用controllers控制器版本出错,这是错误的思考模块化的方法。我使用不同的方法解决了 我的烦恼 ,同时使用class Api::V1::ResourceController < ApplicationController 的继承概念,如:

class Api::V2::ResourceController < Api::V1::ResourceController

之后

def custom_action
    #my custom code here, or use "self"
end

并且行动如下:

var CustomerDB = 
{
  customer:[],
  addresses:[],
  stores:[],
}

var insertData = function(){
  for (var i = 0; i < allData.length; i++)
    //console.log(allData[i]);
      {
          if (allData[i]['type'] == "store")
              {
                  CustomerDB.stores.push(allData[i]);

              }
          else if (allData[i]['type'] == "customer")
              {
                  CustomerDB.customer.push(allData[i]);
              }
          else if (allData[i]['type'] == "address")
              {
                  CustomerDB.addresses.push(allData[i]);
              }
       }
}(); 
希望它对你有所帮助!我以这种方式解决了并且完美无缺!