我正在构建一个带有Rails后端的JS应用程序,为了不混淆蛇和骆驼的情况,我想通过从服务器返回camelcase密钥名称来规范化它。因此,user.last_name
从API返回时会返回user.lastName
。
我如何实现这一目标?谢谢!
修改:添加了控制器代码
class Api::V1::UsersController < API::V1::BaseController
# authorize_resource
respond_to :json, only: [:index]
def sky
@user = User.find_by_id(params[:user_id])
if @user
obj = {
sky: {
sectors: @user.sectors,
slots: @user.slots
}
}
render json: obj
else
raise "Unable to get Sky"
end
end
end
答案 0 :(得分:11)
我这样做的方法是使用ActiveModelSerializer和json_api适配器:
在你的Gemfile中,添加:
gem 'active_model_serializers'
创建一个新文件/config/initializers/ams.rb
,其中包含:
ActiveModelSerializers.config.adapter = :json_api
ActiveModelSerializers.config.key_transform = :camel_lower
您的控制器操作应如下所示:
class ApiController < ApplicationController
def sky
@user = User.find_by_id(params[:user_id])
if @user
render json: @user, serializer: UserSkySerializer
else
raise "Unable to get Sky"
end
end
end
现在您需要创建一个序列化程序。首先,创建一个新目录app/serializers/
。
接下来,创建一个新的序列化程序app/serializers/user_sky_serializer.rb
,其中包含:
class UserSkySerializer < ActiveModel::Serializer
attributes :sectors, :slots
end
结果类似于您在obj
哈希中描述的内容,但所有属性键都将使用jsonapi标准在camelCase中呈现。
答案 1 :(得分:1)
另一个选择是使用olive_branch宝石。如this post中所述,您需要做的是:
config.middleware.use OliveBranch::Middleware
中添加application.rb
。然后,将此标头添加到客户端应用程序的请求中:
'X-Key-Inflection': 'camel'
如果您使用的是axios之类的库,则可以将此标头与其他标头一起添加到常量中:
const HEADERS = {
...
'X-Key-Inflection': 'camel'
}
const request = axios.post(url, param, HEADERS)
这样,您无需在服务器端手动deep_transform
键。甚至深度嵌套的json键也会被驼峰化。此类请求的示例响应:
[
{
"id": 1,
"firstName": "Foo",
"lastName": "Bar",
"createdAt": ...,
"updatedAt": ...,
...
"cabinAssignments": [
{
"id": 1,
"cabinKeeperId": 1,
"userId": 1,
"houseId": 1,
...
}
]
}
]
答案 2 :(得分:0)
你没有提到你的Rails版本,所以对于那些寻找这个的人,我会在Rails 5中提到答案是使用来自ActiveSupport::Inflector
的{{1}}。在我的情况下,我不得不在ActiveRecord
模型(t
下面)的链中调用它:
def index
trucks = AvailableTruck.all.map do |t|
t.as_json(only: AvailableTruck.exposed)
.deep_transform_keys(&:camelize).deep_transform_values(&:upcase)
end
render json: trucks
end
根据您的申请, #deep_transform_keys
可能需要也可能不需要。
答案 3 :(得分:-1)
您可以使用ruby的method_missing
方法实现这一目标。
创建类似concerns/method_missing_extension.rb
的文件,并在其中加入以下代码。
module MethodMissingExtension
def method_missing(method_name, args = {})
if self.class.column_names.include? method_name.to_s.underscore
send method_name.to_s.underscore.to_sym
else
super
end
end
end
在每个模型中加入此模块,例如include MethodMissingExtension
。
现在只要你user.firstName
,user.first_name
就会返回。