我有一个返回一些参数的模型,并包含来自其他模型的参数,如下所示:
def as_json(options = {})
camelize_keys(super(options.merge(:only => [:id, :userId], include:{
comments: { only: [:test, :id] },
valediction: { only: [:name, :text, :hidden, :order] }
})))
end
def camelize_keys(hash)
values = hash.map do |key, value|
[key.camelize(:lower), value]
end
Hash[values]
end
现在我已将代码移动到我的控制器,因为不同的控制器操作需要返回模型的不同部分。 (索引应该只返回告别,但show应该返回评论和告别)
新控制器:
def index
respond_with(displayed_user.microposts.all, include: {
valediction: { only: [:name, :text] }
})
end
def show
respond_with(displayed_user.microposts.find(params[:id]), include: {
comments: { only: [:test, :id] },
valediction: { only: [:name, :text, :hidden, :order] }
})
end
但我对rails非常陌生,我不知道如何将camelize_keys函数放入其中以便它可以工作。
答案 0 :(得分:0)
您可以将方法移动到模型中的类方法,例如
#class methods
class << self
def camelize_keys(hash)
values = hash.map do |key, value|
[key.camelize(:lower), value]
end
Hash[values]
end
end
现在你可以从
这样的地方调用它MyModel.camelize_keys(some_hash)
答案 1 :(得分:0)
在控制器/和/或模型中执行复杂的JSON格式化通常会导致膨胀并且很难测试。
一个很好的解决方案是使用ActiveModel::Serializer(AMS)gem。它包含在Rails 5中,但您可以通过将其添加到gemfile中轻松地将其添加到Rails 4项目中:
# See rubygems.org for latest verstion!
gem 'active_model_serializers', '~> 0.9.3'
然后运行bundle install
并重新启动rails服务器。
使用AMS,您可以创建序列化程序类,这些类定义了如何使用JSON,XML等表示模型数据。序列化程序基本上是一个接受模型实例(或模型数组)并返回哈希(或数组)的类哈希)当你致电.serializable_hash
时。
但Rails会自动为您处理该部分。
class MicropostSerializer < ActiveModel::Serializer
attributes :id, :user_id
has_many :comments
has_many :valedictions
end
class CommentSerializer < ActiveModel::Serializer
attributes :test, :id
end
class ValedictionSerializer < ActiveModel::Serializer
attributes :name, :text, :hidden, :order
end
在您的控制器中,您只需致电:
def index
render json: displayed_user.microposts.all
end
camelize_keys
怎么办?除非你必须支持一些需要camelized密钥的奇怪遗留客户端,否则很少有理由这样做。大多数大型API使用snakecase(Facebook,Google等),而Rails 5正朝着使用snakecase的JSONAPI规范发展。
从您的代码示例中,您的某些rails模型属性(以及支持它们的db列)似乎使用了camelcase。您应该尽快通过迁移更改DB列。
如果您必须支持旧数据库,则可以使用alias_attribute:
class Pet < ActiveRecord::Base
alias_attribute :ownerId, :owner_id
end