我有一个模型和2个控制器如下:
class MyModel < ActiveRecord::Base
def serializable_hash(options={})
super(only: [:id, :foo])
end
end
module V1
class MyController < ApplicationController
def show
render json: {my_model: @my_model}
end
end
end
module V2
class MyController < ApplicationController
def show
render json: {my_model: @my_model}
end
end
end
我希望能够根据控制器返回不同的json:
class MyModel < ActiveRecord::Base
def serializable_hash(options={})
# If V1
super(only: [:id, :foo])
# ElsIf V2
super(only: [:id, :bar])
# End
end
end
我想找到一个通用解决方案,所以我不必在参数中手动发送版本。
答案 0 :(得分:0)
最好将序列化与模型分离,即不要将序列化代码放在模型中。您有以下几种选择:在您的views目录中使用json builder,或使用ActiveModelSerializers。这两种方法都可以轻松地对序列化代码进行版本化处理:
JSON构建器:
# app/views/v1/my_controller/my_model.json.builder
json.my_model do
json.id @my_model.id
json.foo @my_model.foo
end
通过上面的设置,您可以想象使用不同的序列化程序轻松添加v2目录。
在您的控制器中,您甚至不需要指定render
电话,因为rails会注意到您的控制器的视图目录中有一个构建器。 More info about jbuilder in this Railscast
ActiveModelSerializers:
与序列化程序相同,它们只是app / serializers中的文件。您可以将文件放在app/serializers/v1/my_model_serializer.rb
中。
这两种方法的概念是使用Rails模块化路径来版本化您的文件。 app / controller / v1中的控制器将使用相同的v1:app / serializers / v1从其他目录加载文件。
Here's the railscast for active model serializers。 And the asciicast
此外,这里有一个帮助api版本化的宝石:https://github.com/EDMC/api-versions我使用它并发现它很适合。