2014-07-22 52 views

回答

6

更正:你可以做这样的事情

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

使用此方法,您可以为每个模型指定序列化程序类,列出a降低了属性,这将成为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响应进行大量定制,这是一种更简洁的方法。

+0

此外,我不喜欢使用jbuilder或rabl,而更喜欢使用https://github.com/rails-api/active_model_serializers Active Model Serializer。 – dasnixon

+1

'{include:{stadiums:{except::foo}}}''语法不适用于'except',只有'methods'这样的东西?我目前无法测试。 –

+0

@DaveNewton这是可行的。看起来我有点不小心。 – lorefnon

1

怎么回合增加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。没有必要告诉导轨排除在每一个单一的模型,因此保持代码真正干燥