Rails 4 - 从渲染中删除“created_at”和“updated_at”

时间:2014-07-22 18:11:21

标签: ruby-on-rails

当我想从一个资源中删除这些数据时,我会这样做:

@teams = Team.all

render json: @teams, :except => [:created_at, :updated_at],

我怀疑的是,当我有很多这样的包括:

@teams = Team.all

render json: @teams, :include => [:stadiums, :scores, :links, :rounds]

如何从所有这些中删除?

2 个答案:

答案 0 :(得分:7)

更正:您可以执行类似

的操作
render json: @teams.to_json(:except => [:created_at, :updated_at], :include => { :stadiums => { :except => [:created_at, :updated_at]}, ... })

没有迭代相关模型,获取属性哈希并选择所需属性,没有简单的方法。

这些用例通常使用json模板DSL(如jbuilderrabl)优雅地解决。

使用jbuilder来说明这一点:

Jbuilder.encode do |json|
  json.array! @teams do |team|
    json.name team.name
    json.stadiums team.stadiums do |stadium|
      json.name stadium.name
      # Other relevant attributes from stadium
    end
    # Likewise for scores, links, rounds
  end
end

哪个会产生输出:

[{
  name: "someteamname",
  stadiums: {
    name: "stadiumname"
  },
  ...
}, {...},...]

如果您发现这个用例过于冗长,正如@liamneesonsarmsauce在评论中指出的那样,另一种解决方案是使用ActiveModel Serializers

使用此方法,您可以为每个模型指定一个序列化程序类,列出允许的属性,这些属性将成为json响应的一部分。例如

class TeamSerializer  < ActiveModel::Serializer
  attributes :id, :name # Whitelisted attributes

  has_many :stadiums
  has_many :scores
  has_many :links
  has_many :rounds
end

您也可以为关联模型定义类似的序列化器。

由于关联是以rails开发人员已经熟悉的方式无缝处理的,除非您需要对生成的json响应进行大量自定义,否则这是一种更简洁的方法。

答案 1 :(得分:2)

如何&#39; bout添加到models/application_record.rb

# Ignore created_at and updated_at by default in JSONs 
# and when needed add them to :include
def serializable_hash(options={})
  options[:except] ||= []
  options[:except] << :created_at unless (options[:include] == :created_at) || (options[:include].kind_of?(Array) && (options[:include].include? :created_at))
  options[:except] << :updated_at unless (options[:include] == :updated_at) || (options[:include].kind_of?(Array) && (options[:include].include? :updated_at))

  options.delete(:include) if options[:include] == :created_at
  options.delete(:include) if options[:include] == :updated_at
  options[:include] -= [:created_at, :updated_at] if options[:include].kind_of?(Array)

  super(options)
end

然后像

一样使用它
render json: @user
# all except timestamps :created_at and :updated_at

render json: @user, include: :created_at
# all except :updated_at

render json: @user, include: [:created_at, :updated_at]
# all attribs

render json: @user, only: [:id, :created_at]
# as mentioned

render json: @user, include: :posts
# hurray, no :created_at and :updated_at in users and in posts inside users

render json: @user, include: { posts: { include: :created_at }}
# only posts have created_at timestamp

所以在你的情况下,你的代码保持不变

@teams = Team.all
render json: @teams, :include => [:stadiums, :scores, :links, :rounds]

是的,如果没有:created_at:updated_at,你就会得到它们。无需告诉 rails 将其排除在每个模型中,从而保持代码真正的DRY