繁体   English   中英

如何在Rails中对带有json数据的response_with运行方法?

[英]How do I run methods on respond_with json data in Rails?

我有一个模型,该模型返回一些参数,并包括来自其他模型的参数,如下所示:

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

现在,我已将代码移至控制器,因为不同的控制器动作需要返回模型的不同部分。 (索引应该只返回valediction,但是show应该返回注释和valediction)

新的控制器:

  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函数放入其中以使其正常工作。

您可以将方法移至模型中的类方法,例如

#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)

在控制器/和/或模型中执行复杂的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呢?

除非您必须支持一些需要驼峰式密钥的古怪客户端,否则很少有理由这样做。 大多数大型API都使用snakecase(Facebook,Google等),并且Rails 5正在朝着使用snakecase的JSONAPI规范发展。

从代码示例中,您的某些rails模型属性(以及支持它们的db列)似乎使用了camelcase。 您应该尽快通过迁移更改数据库列。

如果您必须支持旧版数据库,则可以使用alias_attribute:

class Pet < ActiveRecord::Base
  alias_attribute :ownerId, :owner_id
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM