2014-07-22 76 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。沒有必要告訴導軌排除在每一個單一的模型,因此保持代碼真正乾燥