2017-06-16 14 views
2

我正在构建一个带有Rails后端的JS应用程序,为了不混淆蛇和骆驼事件,我想通过从服务器返回camelcase键名来规范化它。因此,当从API返回时,user.last_name将返回user.lastName如何使用camelcased键名从Rails返回JSON

我该如何做到这一点?谢谢!

编辑:新增控制器代码

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 

回答

8

我这样做是使用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标准呈现。

+0

感谢moveson,我这样做,并且我得到了JSON序列化版本'[active_model_serializers]加载ActiveModel渲染::串行::空与Hash'在我的控制台。这里的任何想法? –

+0

难道是因为如果我的继承? '类的API :: V1 :: UsersController

+0

FWIW,这是一个Rails应用程序,而不是一个轨道的API的应用程序 –

-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将返回。

+0

我讨厌downvote的没有理由。 Downvoters任何理由downvote? –

+0

当然,我投了票,因为类似的答案已经存在,我写了一个评论,说明为什么。我只把它投下来,作为未来遇到这个问题的人的一个信号,说明正确的答案可能在哪里。希望清除它 –

+0

这个答案是非常不同的。他们的'method_missing'的实现有点不同,需要为每个模型的每个属性创建它。但是,这里只有一次写入的模块可以包含在所有需要的“模型”中,并且您可以获得理想的结果。希望它能澄清你的困惑。 –

0

你没有提到你的Rails版本,所以对于其他寻找这个的人,我会提到在Rails 5中,答案是使用ActiveSupport::Inflector中的#camelize。就我而言,我不得不把它调用链上的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根据您的应用程序可能会或可能不会是必要的。

+0

我正在使用Rails 5 –

+0

在你的例子中't'是什么?你可以给你的代码多一点背景吗? –

+0

那么也许它会更好地使用这种方法? –